diff --git a/CHANGES b/CHANGES
index 6e6bec6d07a68b22a2b8612af3ce592499da7b11..cbe03fd3e54ee2d1145ed39c80370e9975017114 100644
--- a/CHANGES
+++ b/CHANGES
@@ -397,8 +397,6 @@ res_pjsip
     "contact_deny" - List of Contact header addresses to deny
     "contact_permit" - List of Contact header addresses to permit
 
- * Added new status Updated to AMI event ContactStatus on update registration
-
  * Added "reg_server" to contacts.
    If the Asterisk system name is set in asterisk.conf, it will be stored
    into the "reg_server" field in the ps_contacts table to facilitate
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index f9f9e2037ebf4ea7f7d1e19d1563687522571e2f..f43a11cb04f4a434e690937386b25b738084c501 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -271,7 +271,6 @@ enum ast_sip_contact_status_type {
 	UNKNOWN,
 	CREATED,
 	REMOVED,
-	UPDATED,
 };
 
 /*!
@@ -296,6 +295,8 @@ struct ast_sip_contact_status {
 	int64_t rtt;
 	/*! Last status for a contact (default - unavailable) */
 	enum ast_sip_contact_status_type last_status;
+	/*! TRUE if the contact was refreshed. e.g., re-registered */
+	unsigned int refresh:1;
 };
 
 /*!
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index 8a5ff416ad6a09ce0a65257528a4fda65430f920..6890cedf0a857cb9f2012b57fc678a80331ad7e8 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -105,6 +105,40 @@ static void endpoint_update_state(struct ast_endpoint *endpoint, enum ast_endpoi
 	ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "PJSIP/%s", ast_endpoint_get_resource(endpoint));
 }
 
+static void endpoint_publish_contact_status(struct ast_endpoint *endpoint, struct ast_sip_contact_status *contact)
+{
+	struct ast_json *blob;
+	char rtt[32];
+
+	snprintf(rtt, sizeof(rtt), "%" PRId64, contact->rtt);
+	blob = ast_json_pack("{s: s, s: s, s: s, s: s, s: s}",
+		"contact_status", ast_sip_get_contact_status_label(contact->status),
+		"aor", contact->aor,
+		"uri", contact->uri,
+		"roundtrip_usec", rtt,
+		"endpoint_name", ast_endpoint_get_resource(endpoint));
+	if (blob) {
+		ast_endpoint_blob_publish(endpoint, ast_endpoint_contact_state_type(), blob);
+		ast_json_unref(blob);
+	}
+}
+
+/*! \brief Callback function for publishing the status of an endpoint */
+static int persistent_endpoint_publish_status(void *obj, void *arg, int flags)
+{
+	struct sip_persistent_endpoint *persistent = obj;
+	struct ast_endpoint *endpoint = persistent->endpoint;
+	struct ast_sip_contact_status *status = arg;
+
+	/* If the status' aor isn't one of the endpoint's, we skip */
+	if (!strstr(persistent->aors, status->aor)) {
+		return 0;
+	}
+
+	endpoint_publish_contact_status(endpoint, status);
+	return 0;
+}
+
 /*! \brief Callback function for changing the state of an endpoint */
 static int persistent_endpoint_update_state(void *obj, void *arg, int flags)
 {
@@ -112,30 +146,17 @@ static int persistent_endpoint_update_state(void *obj, void *arg, int flags)
 	struct ast_endpoint *endpoint = persistent->endpoint;
 	struct ast_sip_contact_status *status = arg;
 	struct ao2_container *contacts;
-	struct ast_json *blob;
 	struct ao2_iterator i;
 	struct ast_sip_contact *contact;
 	enum ast_endpoint_state state = AST_ENDPOINT_OFFLINE;
 
-	if (status) {
-		char rtt[32];
-
-		/* If the status' aor isn't one of the endpoint's, we skip */
-		if (!strstr(persistent->aors, status->aor)) {
-			return 0;
-		}
-
-		snprintf(rtt, sizeof(rtt), "%" PRId64, status->rtt);
-		blob = ast_json_pack("{s: s, s: s, s: s, s: s, s: s}",
-			"contact_status", ast_sip_get_contact_status_label(status->status),
-			"aor", status->aor,
-			"uri", status->uri,
-			"roundtrip_usec", rtt,
-			"endpoint_name", ast_endpoint_get_resource(endpoint));
-		ast_endpoint_blob_publish(endpoint, ast_endpoint_contact_state_type(), blob);
-		ast_json_unref(blob);
+	/* If the status' aor isn't one of the endpoint's, we skip */
+	if (!strstr(persistent->aors, status->aor)) {
+		return 0;
 	}
 
+	endpoint_publish_contact_status(endpoint, status);
+
 	/* Find all the contacts for this endpoint.  If ANY are available,
 	 * mark the endpoint as ONLINE.
 	 */
@@ -222,6 +243,13 @@ static void persistent_endpoint_contact_status_observer(const void *object)
 {
 	struct ast_sip_contact_status *contact_status = (struct ast_sip_contact_status *)object;
 
+	if (contact_status->refresh) {
+		/* We are only re-publishing the contact status. */
+		ao2_callback(persistent_endpoints, OBJ_NODATA,
+			persistent_endpoint_publish_status, contact_status);
+		return;
+	}
+
 	/* If rtt_start is set (this is the outgoing OPTIONS), ignore. */
 	if (contact_status->rtt_start.tv_sec > 0) {
 		return;
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index dc3bce06f1d23e15476f97954cb1e626c3fa607f..808ee171a1c53749cc6b4abce3dfff5a60233862 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -43,7 +43,6 @@ static const char *status_map [] = {
 	[UNKNOWN] = "Unknown",
 	[CREATED] = "Created",
 	[REMOVED] = "Removed",
-	[UPDATED] = "Updated",
 };
 
 static const char *short_status_map [] = {
@@ -52,7 +51,6 @@ static const char *short_status_map [] = {
 	[UNKNOWN] = "Unknown",
 	[CREATED] = "Created",
 	[REMOVED] = "Removed",
-	[UPDATED] = "Updated",
 };
 
 const char *ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status)
@@ -157,7 +155,7 @@ struct ast_sip_contact_status *ast_res_pjsip_find_or_create_contact_status(const
  * \brief Update an ast_sip_contact_status's elements.
  */
 static void update_contact_status(const struct ast_sip_contact *contact,
-	enum ast_sip_contact_status_type value)
+	enum ast_sip_contact_status_type value, int is_contact_refresh)
 {
 	RAII_VAR(struct ast_sip_contact_status *, status, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_sip_contact_status *, update, NULL, ao2_cleanup);
@@ -169,6 +167,26 @@ static void update_contact_status(const struct ast_sip_contact *contact,
 		return;
 	}
 
+	if (is_contact_refresh
+		&& status->status == CREATED) {
+		/*
+		 * The contact status hasn't been updated since creation
+		 * and we don't want to re-send a created status.
+		 */
+		if (contact->qualify_frequency
+			|| status->rtt_start.tv_sec > 0) {
+			/* Ignore, the status will change soon. */
+			return;
+		}
+
+		/*
+		 * Convert to a regular contact status update
+		 * because the status may never change.
+		 */
+		is_contact_refresh = 0;
+		value = UNKNOWN;
+	}
+
 	update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
 		ast_sorcery_object_get_id(status));
 	if (!update) {
@@ -178,22 +196,35 @@ static void update_contact_status(const struct ast_sip_contact *contact,
 	}
 
 	ast_string_field_set(update, uri, contact->uri);
-	update->last_status = status->status;
-	update->status = value;
-
-	/* if the contact is available calculate the rtt as
-	   the diff between the last start time and "now" */
-	update->rtt = update->status == AVAILABLE && status->rtt_start.tv_sec > 0 ?
-		ast_tvdiff_us(ast_tvnow(), status->rtt_start) : 0;
-	update->rtt_start = ast_tv(0, 0);
-
-	ast_test_suite_event_notify("AOR_CONTACT_QUALIFY_RESULT",
-		"Contact: %s\r\n"
-		"Status: %s\r\n"
-		"RTT: %" PRId64,
-		ast_sorcery_object_get_id(update),
-		ast_sip_get_contact_status_label(update->status),
-		update->rtt);
+
+	if (is_contact_refresh) {
+		/* Copy everything just to set the refresh flag. */
+		update->status = status->status;
+		update->last_status = status->last_status;
+		update->rtt = status->rtt;
+		update->rtt_start = status->rtt_start;
+		update->refresh = 1;
+	} else {
+		update->last_status = status->status;
+		update->status = value;
+
+		/*
+		 * if the contact is available calculate the rtt as
+		 * the diff between the last start time and "now"
+		 */
+		update->rtt = update->status == AVAILABLE && status->rtt_start.tv_sec > 0
+			? ast_tvdiff_us(ast_tvnow(), status->rtt_start)
+			: 0;
+		update->rtt_start = ast_tv(0, 0);
+
+		ast_test_suite_event_notify("AOR_CONTACT_QUALIFY_RESULT",
+			"Contact: %s\r\n"
+			"Status: %s\r\n"
+			"RTT: %" PRId64,
+			ast_sorcery_object_get_id(update),
+			ast_sip_get_contact_status_label(update->status),
+			update->rtt);
+	}
 
 	if (ast_sorcery_update(ast_sip_get_sorcery(), update)) {
 		ast_log(LOG_ERROR, "Unable to update ast_sip_contact_status for contact %s\n",
@@ -306,10 +337,10 @@ static void qualify_contact_cb(void *token, pjsip_event *e)
 		/* Fall through */
 	case PJSIP_EVENT_TRANSPORT_ERROR:
 	case PJSIP_EVENT_TIMER:
-		update_contact_status(contact, UNAVAILABLE);
+		update_contact_status(contact, UNAVAILABLE, 0);
 		break;
 	case PJSIP_EVENT_RX_MSG:
-		update_contact_status(contact, AVAILABLE);
+		update_contact_status(contact, AVAILABLE, 0);
 		break;
 	}
 	ao2_cleanup(contact);
@@ -365,7 +396,7 @@ static int qualify_contact(struct ast_sip_endpoint *endpoint, struct ast_sip_con
 		!= PJ_SUCCESS) {
 		ast_log(LOG_ERROR, "Unable to send request to qualify contact %s\n",
 			contact->uri);
-		update_contact_status(contact, UNAVAILABLE);
+		update_contact_status(contact, UNAVAILABLE, 0);
 		ao2_ref(contact, -1);
 		return -1;
 	}
@@ -525,7 +556,7 @@ static void qualify_and_schedule(struct ast_sip_contact *contact)
 
 		schedule_qualify(contact, contact->qualify_frequency * 1000);
 	} else {
-		update_contact_status(contact, UNKNOWN);
+		update_contact_status(contact, UNKNOWN, 0);
 	}
 }
 
@@ -544,8 +575,7 @@ static void contact_created(const void *obj)
  */
 static void contact_updated(const void *obj)
 {
-	update_contact_status((struct ast_sip_contact *) obj, UPDATED);
-	qualify_and_schedule((struct ast_sip_contact *) obj);
+	update_contact_status(obj, AVAILABLE, 1);
 }
 
 /*!
@@ -574,8 +604,8 @@ static void contact_deleted(const void *obj)
 
 static const struct ast_sorcery_observer contact_observer = {
 	.created = contact_created,
+	.updated = contact_updated,
 	.deleted = contact_deleted,
-	.updated = contact_updated
 };
 
 static pj_bool_t options_start(void)
@@ -1051,7 +1081,7 @@ static void qualify_and_schedule_contact(struct ast_sip_contact *contact)
 	if (contact->qualify_frequency) {
 		schedule_qualify(contact, initial_interval);
 	} else {
-		update_contact_status(contact, UNKNOWN);
+		update_contact_status(contact, UNKNOWN, 0);
 	}
 }