diff --git a/include/asterisk/dial.h b/include/asterisk/dial.h
index c59257ce5b367d680a26f46813f4b6d5150d2057..168c5091aa7cea69fba7ad40937c32dc3428d7a2 100644
--- a/include/asterisk/dial.h
+++ b/include/asterisk/dial.h
@@ -76,6 +76,18 @@ struct ast_dial *ast_dial_create(void);
  */
 int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids);
 
+/*!
+ * \brief Append a channel using an actual channel object
+ *
+ * \param dial The ast_dial to add the channel to
+ * \param chan The channel to add to the dial
+ * \retval -1 Failure
+ * \retval non-zero The position of the channel in the list of dialed channels
+ *
+ * \note The chan ref is stolen with a successful return.
+ */
+int ast_dial_append_channel(struct ast_dial *dial, struct ast_channel *chan);
+
 /*! \brief Request all appended channels, but do not dial
  * \param dial Dialing structure
  * \param chan Optional dialing channel
diff --git a/main/dial.c b/main/dial.c
index 127f327d1a39bef7c541bb1780b7c88c3575009d..80247588d924d57f378ec37d20dfc17ac07112e9 100644
--- a/main/dial.c
+++ b/main/dial.c
@@ -248,22 +248,9 @@ struct ast_dial *ast_dial_create(void)
 	return dial;
 }
 
-/*! \brief Append a channel
- * \note Appends a channel to a dialing structure
- * \return Returns channel reference number on success, -1 on failure
- */
-int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
+static int dial_append_common(struct ast_dial *dial, struct ast_dial_channel *channel,
+		const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
 {
-	struct ast_dial_channel *channel = NULL;
-
-	/* Make sure we have required arguments */
-	if (!dial || !tech || !device)
-		return -1;
-
-	/* Allocate new memory for dialed channel structure */
-	if (!(channel = ast_calloc(1, sizeof(*channel))))
-		return -1;
-
 	/* Record technology and device for when we actually dial */
 	channel->tech = ast_strdup(tech);
 	channel->device = ast_strdup(device);
@@ -287,6 +274,60 @@ int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device,
 	AST_LIST_INSERT_TAIL(&dial->channels, channel, list);
 
 	return channel->num;
+
+}
+
+/*! \brief Append a channel
+ * \note Appends a channel to a dialing structure
+ * \return Returns channel reference number on success, -1 on failure
+ */
+int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
+{
+	struct ast_dial_channel *channel = NULL;
+
+	/* Make sure we have required arguments */
+	if (!dial || !tech || !device)
+		return -1;
+
+	/* Allocate new memory for dialed channel structure */
+	if (!(channel = ast_calloc(1, sizeof(*channel))))
+		return -1;
+
+	return dial_append_common(dial, channel, tech, device, assignedids);
+}
+
+int ast_dial_append_channel(struct ast_dial *dial, struct ast_channel *chan)
+{
+	struct ast_dial_channel *channel;
+	char *tech;
+	char *device;
+	char *dash;
+
+	if (!dial || !chan) {
+		return -1;
+	}
+
+	channel = ast_calloc(1, sizeof(*channel));
+	if (!channel) {
+		return -1;
+	}
+	channel->owner = chan;
+
+	tech = ast_strdupa(ast_channel_name(chan));
+
+	device = strchr(tech, '/');
+	if (!device) {
+		ast_free(channel);
+		return -1;
+	}
+	*device++ = '\0';
+
+	dash = strrchr(device, '-');
+	if (dash) {
+		*dash = '\0';
+	}
+
+	return dial_append_common(dial, channel, tech, device, NULL);
 }
 
 /*! \brief Helper function that requests all channels */
@@ -315,27 +356,29 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
 		}
 	}
 
-	/* Copy device string over */
-	ast_copy_string(numsubst, channel->device, sizeof(numsubst));
+	if (!channel->owner) {
+		/* Copy device string over */
+		ast_copy_string(numsubst, channel->device, sizeof(numsubst));
 
-	if (cap && ast_format_cap_count(cap)) {
-		cap_request = cap;
-	} else if (requester_cap) {
-		cap_request = requester_cap;
-	} else {
-		cap_all_audio = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
-		ast_format_cap_append_by_type(cap_all_audio, AST_MEDIA_TYPE_AUDIO);
-		cap_request = cap_all_audio;
-	}
+		if (cap && ast_format_cap_count(cap)) {
+			cap_request = cap;
+		} else if (requester_cap) {
+			cap_request = requester_cap;
+		} else {
+			cap_all_audio = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+			ast_format_cap_append_by_type(cap_all_audio, AST_MEDIA_TYPE_AUDIO);
+			cap_request = cap_all_audio;
+		}
 
-	/* If we fail to create our owner channel bail out */
-	if (!(channel->owner = ast_request(channel->tech, cap_request, &assignedids, chan, numsubst, &channel->cause))) {
+		/* If we fail to create our owner channel bail out */
+		if (!(channel->owner = ast_request(channel->tech, cap_request, &assignedids, chan, numsubst, &channel->cause))) {
+			ao2_cleanup(cap_all_audio);
+			return -1;
+		}
+		cap_request = NULL;
+		ao2_cleanup(requester_cap);
 		ao2_cleanup(cap_all_audio);
-		return -1;
 	}
-	cap_request = NULL;
-	ao2_cleanup(requester_cap);
-	ao2_cleanup(cap_all_audio);
 
 	if (chan) {
 		ast_channel_lock_both(chan, channel->owner);