diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 72c3416bd23f0af3b1d8f8165264935e08c9c053..b3ee6c395bc8c56ad50938e0137dff4f9a838498 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -890,6 +890,8 @@ struct ast_sip_endpoint {
 		AST_STRING_FIELD(messages_waiting);
 		/*! Dialtone to be used as audiable indication when there is a message waiting for the endpoint */
 		AST_STRING_FIELD(mwi_dialtone_state);
+		/*Direction for the P-Early-Media */
+		AST_STRING_FIELD(direction);
 	);
 	/*! Configuration for extensions */
 	struct ast_sip_endpoint_extensions extensions;
@@ -963,6 +965,9 @@ struct ast_sip_endpoint {
 	unsigned int mediasec;
 	/*! Call waiting enabled flag */
 	unsigned int call_waiting_enabled;
+	/*! Support earlyMedia on endpoint */
+	unsigned int earlymedia;
+        
 	/*! Security mechanisms supported by peer */
 	AST_LIST_HEAD_NOLOCK(, security_mechanism) security_mechanisms;
 };
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index c8ff6b4f61528f53416eec3de757a1a77d0da05a..5cd960068a539905d34fa1a814c541018ad21d3a 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -2117,6 +2117,8 @@ int ast_res_pjsip_initialize_configuration(void)
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "timers", "yes", timers_handler, timers_to_str, NULL, 0, 0);
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "timers_min_se", "90", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, extensions.timer.min_se));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "timers_sess_expires", "1800", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, extensions.timer.sess_expires));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "earlymedia", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, earlymedia));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "direction", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint , direction));
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "auth", "", inbound_auth_handler, inbound_auths_to_str, NULL, 0, 0);
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "outbound_auth", "", outbound_auth_handler, outbound_auths_to_str, NULL, 0, 0);
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "aors", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, aors));
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 6af6b8a8dcb2d9af807fa559d538c3618c974634..3e68ae87edc3c09bb0b6ec95c5453451af8769c6 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -66,7 +66,7 @@
 static int max_sessions_per_line = DEFAULT_MAX_SESSION_PER_LINE;
 static int max_sessions = DEFAULT_MAX_SESSION;
 static int current_session_count = 0;          // current number of active sessions
-
+#define MAX_BUFFER_LEN 50
 /* Some forward declarations */
 static void handle_session_begin(struct ast_sip_session *session);
 static void handle_session_end(struct ast_sip_session *session);
@@ -2540,6 +2540,7 @@ static int sip_session_refresh(struct ast_sip_session *session,
 			}
 		}
 	}
+
 	ast_sip_session_send_request_with_cb(session, tdata, on_response);
 	ast_sip_session_media_state_free(active_media_state);
 
@@ -2609,6 +2610,8 @@ void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_dat
 
 static pj_bool_t session_on_rx_request(pjsip_rx_data *rdata);
 static pj_bool_t session_on_rx_response(pjsip_rx_data *rdata);
+static pj_status_t add_earlymedia_request_headers(pjsip_tx_data *tdata);
+static pj_status_t add_earlymedia_response_headers(pjsip_tx_data *tdata);
 static void session_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e);
 
 static pjsip_module session_module = {
@@ -2617,6 +2620,8 @@ static pjsip_module session_module = {
 	.on_rx_request = session_on_rx_request,
 	.on_rx_response = session_on_rx_response,
 	.on_tsx_state = session_on_tsx_state,
+	.on_tx_request = add_earlymedia_request_headers,
+	.on_tx_response = add_earlymedia_response_headers,
 };
 
 /*! \brief Determine whether the SDP provided requires deferral of negotiating or not
@@ -2873,6 +2878,8 @@ void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data
 int ast_sip_session_create_invite(struct ast_sip_session *session, pjsip_tx_data **tdata)
 {
 	pjmedia_sdp_session *offer;
+	pjsip_generic_string_hdr *content_header = NULL;
+	static const pj_str_t headerName = { "Content-Disposition", 19 };
 	SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
 
 	if (!(offer = create_local_sdp(session->inv_session, session, NULL))) {
@@ -2913,6 +2920,19 @@ int ast_sip_session_create_invite(struct ast_sip_session *session, pjsip_tx_data
 		}
 	}
 
+	content_header = pjsip_msg_find_hdr_by_name((*tdata)->msg, &headerName, NULL);
+	/*If content dispostion is present P-Early-Media header field does not apply*/
+	if (content_header)
+	{
+		char content_header_value[MAX_BUFFER_LEN] = {0};
+		ast_copy_pj_str(&content_header_value, &content_header->hvalue, pj_strlen(&content_header->hvalue) + 1);
+		if(!strcmp(content_header_value, "early-session"))
+			session->endpoint->earlymedia = 0;
+	}
+
+	if(session->endpoint->earlymedia)
+		ast_sip_add_header(*tdata,"P-Early-Media","supported");
+
 	SCOPE_EXIT_RTN_VALUE(0);
 }
 
@@ -4277,7 +4297,88 @@ static pj_bool_t has_supplement(const struct ast_sip_session *session, const pjs
 	}
 	return PJ_FALSE;
 }
+/*Parse the direction and remove redundant values*/
+static void parse_earlymedia_direction(char *direction, char *buffer)
+{
+	char directionbuffer[MAX_BUFFER_LEN];
+	strcpy(directionbuffer, direction);
+	char *token = strtok(directionbuffer, ",");
+	int flag =0;
+
+	while( token != NULL )
+	{
+		if(flag)
+		{
+			sprintf(buffer+strlen(buffer), "%s", ",");
+			flag= 0;
+		}
+		if(!strcmp(token ,"sendrecv") || !strcmp(token ,"sendonly") || !strcmp(token ,"recvonly")
+				|| !strcmp(token ,"inactive"))
+		{
+			sprintf(buffer+strlen(buffer), "%s", token);
+			flag = 1;
+		}
 
+		token = strtok(NULL, ",");
+	}
+	if(buffer[strlen(buffer)-1] == ',')
+	   buffer[strlen(buffer)-1]= '\0';
+}
+
+static pj_status_t add_earlymedia_request_headers(pjsip_tx_data *tdata)
+{
+	pjsip_dialog *dlg = pjsip_tdata_get_dlg(tdata);
+	if(tdata->msg->line.status.code == 6) //Prack
+	{
+		if(dlg)
+		{
+			struct ast_sip_session *session = ast_sip_dialog_get_session(dlg);
+			if(session && session->endpoint->earlymedia)
+			{
+				char buffer[MAX_BUFFER_LEN] = {0};
+				parse_earlymedia_direction(session->endpoint->direction, &buffer);
+				if(strlen(buffer) > 0)
+					ast_sip_add_header(tdata,"P-Early-Media", buffer);
+			}
+		}
+	}
+	return PJ_SUCCESS;
+}
+
+static pj_status_t add_earlymedia_response_headers(pjsip_tx_data *tdata)
+{
+	pjsip_dialog *dlg = pjsip_tdata_get_dlg(tdata);
+	struct pjsip_request_line req = tdata->msg->line.req;
+	pjsip_generic_string_hdr *request_headers = NULL;
+	static const pj_str_t headerName = { "P-Early-Media", 13 };
+	request_headers = pjsip_msg_find_hdr_by_name(tdata->msg, &headerName, NULL);
+
+	/*response is constructed by library,Hence remove the P-Early-Media header
+	  from 200 Ok for invite and error cases*/
+	if (request_headers)
+	{
+		if(tdata->msg->line.status.code != 180 && tdata->msg->line.status.code != 183)
+			pj_list_erase(request_headers);
+	}
+
+	pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);
+	if((tdata->msg->line.status.code == 200 && strcmp(pj_strbuf(&cseq->method.name),"PRACK") == 0) ||
+			(tdata->msg->line.status.code == 200 && strcmp(pj_strbuf(&cseq->method.name),"UPDATE") == 0))
+	{
+		if(dlg)
+		{
+			struct ast_sip_session *session = ast_sip_dialog_get_session(dlg);
+			if(session && session->endpoint->earlymedia)
+			{
+				char buffer[MAX_BUFFER_LEN] = {0};
+				parse_earlymedia_direction(session->endpoint->direction, &buffer);
+				if(strlen(buffer) > 0)
+					ast_sip_add_header(tdata,"P-Early-Media", buffer);
+			}
+		}
+	}
+	return PJ_SUCCESS;
+}
 /*!
  * \internal
  * Added for debugging purposes
@@ -4636,12 +4737,25 @@ static void handle_outgoing_response(struct ast_sip_session *session, pjsip_tx_d
 {
 	struct ast_sip_session_supplement *supplement;
 	struct pjsip_status_line status = tdata->msg->line.status;
+
 	pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);
 	SCOPE_ENTER(3, "%s: Method is %.*s, Response is %d %.*s\n", ast_sip_session_get_name(session),
 		(int) pj_strlen(&cseq->method.name),
 		pj_strbuf(&cseq->method.name), status.code, (int) pj_strlen(&status.reason),
 		pj_strbuf(&status.reason));
 
+	//If earlymedia is enabled add header to 18X responses
+	if(status.code == 180 || status.code == 183)
+	{
+		if(session->endpoint->earlymedia)
+		{
+			ast_log(LOG_NOTICE, "Add the header P-Early-Media to 18X!!");
+			char buffer[MAX_BUFFER_LEN]={0};
+			parse_earlymedia_direction(session->endpoint->direction, &buffer);
+			if(strlen(buffer) > 0)
+			  ast_sip_add_header(tdata, "P-Early-Media", buffer);
+		}
+	}
 
 	if (!cseq) {
 		SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Cannot send response due to missing sequence header",