diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 93889fc11135d6c4ec1e1ef8ea935ab3f8407fac..b6944dbc7ee699e30d5f56598cf4d45218bab0b9 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -689,9 +689,6 @@ static int answer(void *data)
 		ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
 			session->inv_session->cause,
 			pjsip_get_status_text(session->inv_session->cause)->ptr);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-		pjsip_inv_dec_ref(session->inv_session);
-#endif
 		SCOPE_EXIT_RTN_VALUE(0, "Disconnected\n");
 	}
 
@@ -708,10 +705,6 @@ static int answer(void *data)
 		ast_sip_session_send_response(session, packet);
 	}
 
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	pjsip_inv_dec_ref(session->inv_session);
-#endif
-
 	if (status != PJ_SUCCESS) {
 		char err[PJ_ERR_MSG_SIZE];
 
@@ -744,14 +737,6 @@ static int chan_pjsip_answer(struct ast_channel *ast)
 	ast_setstate(ast, AST_STATE_UP);
 	session = ao2_bump(channel->session);
 
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	if (pjsip_inv_add_ref(session->inv_session) != PJ_SUCCESS) {
-		ast_log(LOG_ERROR, "Couldn't increase the session reference counter\n");
-		ao2_ref(session, -1);
-		SCOPE_EXIT_RTN_VALUE(-1, "Couldn't increase the session reference counter\n");
-	}
-#endif
-
 	/* the answer task needs to be pushed synchronously otherwise a race condition
 	   can occur between this thread and bridging (specifically when native bridging
 	   attempts to do direct media) */
@@ -763,9 +748,6 @@ static int chan_pjsip_answer(struct ast_channel *ast)
 		if (res == -1) {
 			ast_log(LOG_ERROR,"Cannot answer '%s': Unable to push answer task to the threadpool.\n",
 				ast_channel_name(session->channel));
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-			pjsip_inv_dec_ref(session->inv_session);
-#endif
 		}
 		ao2_ref(session, -1);
 		ast_channel_lock(ast);
@@ -1358,9 +1340,6 @@ static int indicate(void *data)
 		ast_sip_session_send_response(session, packet);
 	}
 
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	pjsip_inv_dec_ref(session->inv_session);
-#endif
 	ao2_ref(ind_data, -1);
 
 	return 0;
@@ -1392,31 +1371,20 @@ static int transmit_info_with_vidupdate(void *data)
 		ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
 			session->inv_session->cause,
 			pjsip_get_status_text(session->inv_session->cause)->ptr);
-		goto failure;
+		return -1;
 	}
 
 	if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
 		ast_log(LOG_ERROR, "Could not create text video update INFO request\n");
-		goto failure;
+		return -1;
 	}
 	if (ast_sip_add_body(tdata, &body)) {
 		ast_log(LOG_ERROR, "Could not add body to text video update INFO request\n");
-		goto failure;
+		return -1;
 	}
 	ast_sip_session_send_request(session, tdata);
 
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	pjsip_inv_dec_ref(session->inv_session);
-#endif
-
 	return 0;
-
-failure:
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	pjsip_inv_dec_ref(session->inv_session);
-#endif
-	return -1;
-
 }
 
 /*!
@@ -1464,9 +1432,6 @@ static int update_connected_line_information(void *data)
 		ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
 			session->inv_session->cause,
 			pjsip_get_status_text(session->inv_session->cause)->ptr);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-		pjsip_inv_dec_ref(session->inv_session);
-#endif
 		ao2_ref(session, -1);
 		return -1;
 	}
@@ -1507,10 +1472,6 @@ static int update_connected_line_information(void *data)
 		}
 	}
 
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	pjsip_inv_dec_ref(session->inv_session);
-#endif
-
 	ao2_ref(session, -1);
 	return 0;
 }
@@ -1742,18 +1703,9 @@ static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const voi
 					res = ast_rtp_instance_write(media->rtp, &fr);
 				} else {
 					ao2_ref(channel->session, +1);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-					if (pjsip_inv_add_ref(channel->session->inv_session) != PJ_SUCCESS) {
-						ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
+					if (ast_sip_push_task(channel->session->serializer, transmit_info_with_vidupdate, channel->session)) {
 						ao2_cleanup(channel->session);
-					} else {
-#endif
-						if (ast_sip_push_task(channel->session->serializer, transmit_info_with_vidupdate, channel->session)) {
-							ao2_cleanup(channel->session);
-						}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
 					}
-#endif
 				}
 				ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Success");
 			} else {
@@ -1767,17 +1719,7 @@ static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const voi
 		break;
 	case AST_CONTROL_CONNECTED_LINE:
 		ao2_ref(channel->session, +1);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-		if (pjsip_inv_add_ref(channel->session->inv_session) != PJ_SUCCESS) {
-			ao2_cleanup(channel->session);
-			SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't increase the session reference counter\n",
-				ast_channel_name(ast));
-		}
-#endif
 		if (ast_sip_push_task(channel->session->serializer, update_connected_line_information, channel->session)) {
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-			pjsip_inv_dec_ref(channel->session->inv_session);
-#endif
 			ao2_cleanup(channel->session);
 		}
 		break;
@@ -1884,18 +1826,10 @@ static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const voi
 		if (!ind_data) {
 			SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc indicate data\n", ast_channel_name(ast));
 		}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-		if (pjsip_inv_add_ref(ind_data->session->inv_session) != PJ_SUCCESS) {
-			ao2_cleanup(ind_data);
-			SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't increase the session reference counter\n", ast_channel_name(ast));
-		}
-#endif
+
 		if (ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
 			ast_log(LOG_ERROR, "%s: Cannot send response code %d to endpoint %s. Could not queue task properly\n",
 					ast_channel_name(ast), response_code, ast_sorcery_object_get_id(channel->session->endpoint));
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-			pjsip_inv_dec_ref(ind_data->session->inv_session);
-#endif
 			ao2_cleanup(ind_data);
 			res = -1;
 		}
@@ -2166,10 +2100,6 @@ static int transfer(void *data)
 		}
 	}
 
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	pjsip_inv_dec_ref(trnf_data->session->inv_session);
-#endif
-
 	ao2_ref(trnf_data, -1);
 	ao2_cleanup(endpoint);
 	ao2_cleanup(contact);
@@ -2186,19 +2116,8 @@ static int chan_pjsip_transfer(struct ast_channel *chan, const char *target)
 		return -1;
 	}
 
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	if (pjsip_inv_add_ref(trnf_data->session->inv_session) != PJ_SUCCESS) {
-		ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
-		ao2_cleanup(trnf_data);
-		return -1;
-	}
-#endif
-
 	if (ast_sip_push_task(channel->session->serializer, transfer, trnf_data)) {
 		ast_log(LOG_WARNING, "Error requesting transfer\n");
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-		pjsip_inv_dec_ref(trnf_data->session->inv_session);
-#endif
 		ao2_cleanup(trnf_data);
 		return -1;
 	}
@@ -2293,12 +2212,12 @@ static int transmit_info_dtmf(void *data)
 		ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
 			session->inv_session->cause,
 			pjsip_get_status_text(session->inv_session->cause)->ptr);
-		goto failure;
+		return -1;
 	}
 
 	if (!(body_text = ast_str_create(32))) {
 		ast_log(LOG_ERROR, "Could not allocate buffer for INFO DTMF.\n");
-		goto failure;
+		return -1;
 	}
 	ast_str_set(&body_text, 0, "Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
 
@@ -2306,27 +2225,16 @@ static int transmit_info_dtmf(void *data)
 
 	if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
 		ast_log(LOG_ERROR, "Could not create DTMF INFO request\n");
-		goto failure;
+		return -1;
 	}
 	if (ast_sip_add_body(tdata, &body)) {
 		ast_log(LOG_ERROR, "Could not add body to DTMF INFO request\n");
 		pjsip_tx_data_dec_ref(tdata);
-		goto failure;
+		return -1;
 	}
 	ast_sip_session_send_request(session, tdata);
 
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	pjsip_inv_dec_ref(session->inv_session);
-#endif
-
 	return 0;
-
-failure:
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	pjsip_inv_dec_ref(session->inv_session);
-#endif
-	return -1;
-
 }
 
 /*! \brief Function called by core to stop a DTMF digit */
@@ -2367,19 +2275,8 @@ static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned in
 			return -1;
 		}
 
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-		if (pjsip_inv_add_ref(dtmf_data->session->inv_session) != PJ_SUCCESS) {
-			ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
-			ao2_cleanup(dtmf_data);
-			return -1;
-		}
-#endif
-
 		if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
 			ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-			pjsip_inv_dec_ref(dtmf_data->session->inv_session);
-#endif
 			ao2_cleanup(dtmf_data);
 			return -1;
 		}
@@ -2888,10 +2785,6 @@ static int sendtext(void *obj)
 		ast_sip_send_request(tdata, data->session->inv_session->dlg, data->session->endpoint, NULL, NULL);
 	}
 
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	pjsip_inv_dec_ref(data->session->inv_session);
-#endif
-
 	ao2_cleanup(data);
 
 	return 0;
@@ -2913,18 +2806,7 @@ static int chan_pjsip_sendtext_data(struct ast_channel *ast, struct ast_msg_data
 		return -1;
 	}
 
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	if (pjsip_inv_add_ref(data->session->inv_session) != PJ_SUCCESS) {
-		ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
-		ao2_ref(data, -1);
-		return -1;
-	}
-#endif
-
 	if (ast_sip_push_task(channel->session->serializer, sendtext, data)) {
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-		pjsip_inv_dec_ref(data->session->inv_session);
-#endif
 		ao2_ref(data, -1);
 		return -1;
 	}
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 693d432fbcdc9bf8b6fa07b6e8bf21a7286c6ff9..696835414e92a6f56dac91ecb636b2d15159c938 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -2997,7 +2997,16 @@ static void session_destructor(void *obj)
 	ast_dsp_free(session->dsp);
 
 	if (session->inv_session) {
-		pjsip_dlg_dec_session(session->inv_session->dlg, &session_module);
+		struct pjsip_dialog *dlg = session->inv_session->dlg;
+
+		/* The INVITE session uses the dialog pool for memory, so we need to
+		 * decrement its reference first before that of the dialog.
+		 */
+
+#ifdef HAVE_PJSIP_INV_SESSION_REF
+		pjsip_inv_dec_ref(session->inv_session);
+#endif
+		pjsip_dlg_dec_session(dlg, &session_module);
 	}
 
 	ast_test_suite_event_notify("SESSION_DESTROYED", "Endpoint: %s", endpoint_name);
@@ -3105,6 +3114,24 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
 	}
 	ast_sip_dialog_set_serializer(inv_session->dlg, session->serializer);
 	ast_sip_dialog_set_endpoint(inv_session->dlg, endpoint);
+
+	/* When a PJSIP INVITE session is created it is created with a reference
+	 * count of 1, with that reference being managed by the underlying state
+	 * of the INVITE session itself. When the INVITE session transitions to
+	 * a DISCONNECTED state that reference is released. This means we can not
+	 * rely on that reference to ensure the INVITE session remains for the
+	 * lifetime of our session. To ensure it does we add our own reference
+	 * and release it when our own session goes away, ensuring that the INVITE
+	 * session remains for the lifetime of session.
+	 */
+
+#ifdef HAVE_PJSIP_INV_SESSION_REF
+	if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
+		return NULL;
+	}
+#endif
+
 	pjsip_dlg_inc_session(inv_session->dlg, &session_module);
 	inv_session->mod_data[session_module.id] = ao2_bump(session);
 	session->contact = ao2_bump(contact);
@@ -3956,9 +3983,6 @@ static int new_invite(struct new_invite *invite)
 			ast_sip_session_get_name(invite->session),
 			invite->session->inv_session->cause,
 			pjsip_get_status_text(invite->session->inv_session->cause)->ptr);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-		pjsip_inv_dec_ref(invite->session->inv_session);
-#endif
 		SCOPE_EXIT_RTN_VALUE(-1);
 	}
 
@@ -4076,9 +4100,6 @@ static int new_invite(struct new_invite *invite)
 	handle_incoming_request(invite->session, invite->rdata);
 
 end:
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	pjsip_inv_dec_ref(invite->session->inv_session);
-#endif
 	SCOPE_EXIT_RTN_VALUE(0, "%s\n", ast_sip_session_get_name(invite->session));
 }
 
@@ -4124,19 +4145,6 @@ static void handle_new_invite_request(pjsip_rx_data *rdata)
 	 * process handling has successfully completed.
 	 */
 
-
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-	if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
-		ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
-		/* Dialog's lock and a reference are removed in new_invite_initial_answer */
-		if (!new_invite_initial_answer(inv_session, rdata, 500, 500, PJ_FALSE)) {
-			/* Terminate the session if it wasn't done in the answer */
-			pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
-		}
-		SCOPE_EXIT_RTN("Couldn't add invite session reference\n");
-	}
-#endif
-
 	session = ast_sip_session_alloc(endpoint, NULL, inv_session, rdata);
 	if (!session) {
 		/* Dialog's lock and reference are removed in new_invite_initial_answer */
@@ -4144,9 +4152,6 @@ static void handle_new_invite_request(pjsip_rx_data *rdata)
 			/* Terminate the session if it wasn't done in the answer */
 			pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
 		}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
-		pjsip_inv_dec_ref(inv_session);
-#endif
 		SCOPE_EXIT_RTN("Couldn't create session\n");
 	}
 	session->call_direction = AST_SIP_SESSION_INCOMING_CALL;