diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 8785bfa9fb1ba054a0635ed9220cf48ae06979b6..5d879410695cd5b0f8fcd7193d2143043af779cc 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -2041,6 +2041,58 @@ static void xfer_client_on_evsub_state(pjsip_evsub *sub, pjsip_event *event)
 	}
 }
 
+/*! \brief Build the Replace parameter in the URI of Refer-To header field */
+static void sip_build_replaces_param(const struct ast_channel *ast, const char *chan_name, char *replaces, size_t len)
+{
+        struct ast_channel *replaces_chan = ast_channel_get_by_name(chan_name);
+
+        if (replaces_chan == NULL) {
+                ast_log(LOG_NOTICE, "Unable to fetch channel [%s] to be replaced. Refer-To header will be missing "
+                                "Replaces parameter\n", chan_name);
+                return;
+        }
+
+        // Make sure this is a SIP channel too
+        const char *type = ast_channel_tech(replaces_chan)->type;
+        if (strcmp(type, ast_channel_tech(ast)->type) == 0) {
+			struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(replaces_chan);
+
+			if (!channel) {
+				ast_log(LOG_ERROR, "Channel %s has no pvt!\n", ast_channel_name(replaces_chan));
+				return -1;
+			}
+
+			//Get callid and tags from SIP dialog to replace
+			const char *callid = chan_pjsip_get_uniqueid(replaces_chan);
+			const char *totag;
+			const char *fromtag;
+			char tmp[len];
+			char local_tag[pj_strlen(&channel->session->inv_session->dlg->local.info->tag) + 1];
+			char remote_tag[pj_strlen(&channel->session->inv_session->dlg->remote.info->tag) + 1];
+
+			ast_copy_pj_str(local_tag, &channel->session->inv_session->dlg->local.info->tag, sizeof(local_tag));
+			ast_copy_pj_str(remote_tag, &channel->session->inv_session->dlg->remote.info->tag, sizeof(remote_tag));
+
+			if(channel->session->call_direction == AST_SIP_SESSION_OUTGOING_CALL) {
+				totag = remote_tag;
+				fromtag = local_tag;
+			}
+			else {
+				totag = local_tag;
+				fromtag = remote_tag;
+			}
+
+			// Create URI encoded Replaces parameter
+			// ?Replaces=<callid>;to-tag=<totag>;from-tag=<fromtag>
+			snprintf(replaces, len - 1, "%s;to-tag=%s;from-tag=%s", callid, totag, fromtag);
+			ast_uri_encode(replaces, tmp, sizeof(tmp), ast_uri_http);
+			snprintf(replaces, len - 1, "?Replaces=%s", tmp);
+
+        } else {
+                ast_log(LOG_NOTICE, "Asked to replace a call on channel type %s\n", type);
+        }
+}
+
 static void transfer_refer(struct ast_sip_session *session, const char *target)
 {
 	pjsip_evsub *sub;
@@ -2051,6 +2103,9 @@ static void transfer_refer(struct ast_sip_session *session, const char *target)
 	char local_info[pj_strlen(&session->inv_session->dlg->local.info_str) + 1];
 	struct pjsip_evsub_user xfer_cb;
 	struct ast_channel *chan = session->channel;
+	char *chan_name;
+	char referto[256];
+	char replaces[256] = "";
 
 	pj_bzero(&xfer_cb, sizeof(xfer_cb));
 	xfer_cb.on_evsub_state = &xfer_client_on_evsub_state;
@@ -2068,7 +2123,21 @@ static void transfer_refer(struct ast_sip_session *session, const char *target)
 	pjsip_evsub_set_mod_data(sub, refer_callback_module.id, chan);
 	ao2_ref(chan, +1);
 
-	if (pjsip_xfer_initiate(sub, pj_cstr(&tmp, target), &packet) != PJ_SUCCESS) {
+	/* Get the channel name if any */
+	chan_name = strcasestr(target, "?Replaces=");
+	if (chan_name) {
+		*chan_name = '\0';
+		chan_name += strlen("?Replaces=");
+		if (session->channel)
+			sip_build_replaces_param(session->channel, chan_name, replaces, sizeof(replaces));
+		ast_debug(1, "Channel name is [%s], new dest is [%s], final replaces param is [%s]\n",
+				chan_name, target, replaces);
+	}
+
+	snprintf(referto, sizeof(referto), "<sip:%s@%s%s>", target, session->endpoint->fromdomain, replaces);
+	ast_debug(1, "Refer-To: %s\n", referto);
+
+	if (pjsip_xfer_initiate(sub, pj_cstr(&tmp, referto), &packet) != PJ_SUCCESS) {
 		goto failure;
 	}