diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index c488017565a41e6c06ecd795043e325135656e8e..4324d159bcbb21c837c75cfbae38e9c75f689882 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -511,6 +511,11 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s
 	ast_party_id_copy(&ast_channel_caller(chan)->id, &session->id);
 	ast_party_id_copy(&ast_channel_caller(chan)->ani, &session->id);
 
+	if (!ast_strlen_zero(exten)) {
+		/* Set provided DNID on the new channel. */
+		ast_channel_dialed(chan)->number.str = ast_strdup(exten);
+	}
+
 	ast_channel_priority_set(chan, 1);
 
 	ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup);
diff --git a/channels/pjsip/dialplan_functions.c b/channels/pjsip/dialplan_functions.c
index ae1c265bc7ddbcf41790492729d5eb8dcc9ed2c6..4a751230b2baf475563774e092db80d9d332fc4d 100644
--- a/channels/pjsip/dialplan_functions.c
+++ b/channels/pjsip/dialplan_functions.c
@@ -388,7 +388,7 @@
 						</enumlist>
 					</enum>
 					<enum name="target_uri">
-						<para>The request URI of the <literal>INVITE</literal> request associated with the creation of this channel.</para>
+						<para>The contact URI where requests are sent.</para>
 					</enum>
 					<enum name="local_uri">
 						<para>The local URI.</para>
@@ -402,6 +402,10 @@
 					<enum name="remote_tag">
 						<para>Tag in To header</para>
 					</enum>
+					<enum name="request_uri">
+						<para>The request URI of the incoming <literal>INVITE</literal>
+						associated with the creation of this channel.</para>
+					</enum>
 					<enum name="t38state">
 						<para>The current state of any T.38 fax on this channel.</para>
 						<enumlist>
@@ -657,6 +661,27 @@ static int channel_read_rtcp(struct ast_channel *chan, const char *type, const c
 	return 0;
 }
 
+static int print_escaped_uri(struct ast_channel *chan, const char *type,
+	pjsip_uri_context_e context, const void *uri, char *buf, size_t size)
+{
+	int res;
+	char *buf_copy;
+
+	res = pjsip_uri_print(context, uri, buf, size);
+	if (res < 0) {
+		ast_log(LOG_ERROR, "Channel %s: Unescaped %s too long for %d byte buffer\n",
+			ast_channel_name(chan), type, (int) size);
+
+		/* Empty buffer that likely is not terminated. */
+		buf[0] = '\0';
+		return -1;
+	}
+
+	buf_copy = ast_strdupa(buf);
+	ast_escape_quoted(buf_copy, buf, size);
+	return 0;
+}
+
 /*!
  * \internal \brief Handle reading signalling information
  */
@@ -665,6 +690,7 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const
 	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
 	char *buf_copy;
 	pjsip_dialog *dlg;
+	int res = 0;
 
 	if (!channel) {
 		ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
@@ -690,25 +716,27 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const
 		return -1;
 #endif
 	} else if (!strcmp(type, "target_uri")) {
-		pjsip_uri_print(PJSIP_URI_IN_REQ_URI, dlg->target, buf, buflen);
-		buf_copy = ast_strdupa(buf);
-		ast_escape_quoted(buf_copy, buf, buflen);
+		res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI, dlg->target, buf,
+			buflen);
 	} else if (!strcmp(type, "local_uri")) {
-		pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri, buf, buflen);
-		buf_copy = ast_strdupa(buf);
-		ast_escape_quoted(buf_copy, buf, buflen);
+		res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri,
+			buf, buflen);
 	} else if (!strcmp(type, "local_tag")) {
 		ast_copy_pj_str(buf, &dlg->local.info->tag, buflen);
 		buf_copy = ast_strdupa(buf);
 		ast_escape_quoted(buf_copy, buf, buflen);
 	} else if (!strcmp(type, "remote_uri")) {
-		pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dlg->remote.info->uri, buf, buflen);
-		buf_copy = ast_strdupa(buf);
-		ast_escape_quoted(buf_copy, buf, buflen);
+		res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR,
+			dlg->remote.info->uri, buf, buflen);
 	} else if (!strcmp(type, "remote_tag")) {
 		ast_copy_pj_str(buf, &dlg->remote.info->tag, buflen);
 		buf_copy = ast_strdupa(buf);
 		ast_escape_quoted(buf_copy, buf, buflen);
+	} else if (!strcmp(type, "request_uri")) {
+		if (channel->session->request_uri) {
+			res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI,
+				channel->session->request_uri, buf, buflen);
+		}
 	} else if (!strcmp(type, "t38state")) {
 		ast_copy_string(buf, t38state_to_string[channel->session->t38state], buflen);
 	} else if (!strcmp(type, "local_addr")) {
@@ -744,7 +772,7 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const
 		return -1;
 	}
 
-	return 0;
+	return res;
 }
 
 /*! \brief Struct used to push function arguments to task processor */
diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h
index 073cd2e7afeb680dbfdba6abc2d51b87c84ffbbb..57d56318900ff09264492e45839d5d51fa75772c 100644
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -159,6 +159,8 @@ struct ast_sip_session {
 	unsigned int ended_while_deferred:1;
 	/*! DTMF mode to use with this session, from endpoint but can change */
 	enum ast_sip_dtmf_mode dtmf;
+	/*! Initial incoming INVITE Request-URI.  NULL otherwise. */
+	pjsip_uri *request_uri;
 };
 
 typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index f2ee3478b77c392d74ef05cfb074a77b87e5d945..bb53dad09735f34486cd3e2970fc68112bbb447b 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -2019,6 +2019,12 @@ static enum sip_get_destination_result get_destination(struct ast_sip_session *s
 		ast_copy_pj_str(domain, &sip_ruri->host, size);
 		pbx_builtin_setvar_helper(session->channel, "SIPDOMAIN", domain);
 
+		/*
+		 * Save off the INVITE Request-URI in case it is
+		 * needed: CHANNEL(pjsip,request_uri)
+		 */
+		session->request_uri = pjsip_uri_clone(session->inv_session->pool, ruri);
+
 		return SIP_GET_DEST_EXTEN_FOUND;
 	}