diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index ea3a27c8a2bdb23176b3e719c526450e3be8ee2d..9f2cc3d83fe7546243af341a7f7d7602c80317d5 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -964,6 +964,7 @@ struct sip_auth {
 #define SIP_PAGE2_RTCACHEFRIENDS	(1 << 0)	/*!< GP: Should we keep RT objects in memory for extended time? */
 #define SIP_PAGE2_RTAUTOCLEAR		(1 << 2)	/*!< GP: Should we clean memory from peers after expiry? */
 /* Space for addition of other realtime flags in the future */
+#define SIP_PAGE2_STATECHANGEQUEUE	(1 << 9)	/*!< D: Unsent state pending change exists */
 
 #define SIP_PAGE2_VIDEOSUPPORT		(1 << 14)	/*!< DP: Video supported if offered? */
 #define SIP_PAGE2_TEXTSUPPORT		(1 << 15)	/*!< GDP: Global text enable */
@@ -1262,7 +1263,7 @@ struct sip_pvt {
 	int noncecount;				/*!< Nonce-count */
 	char lastmsg[256];			/*!< Last Message sent/received */
 	int amaflags;				/*!< AMA Flags */
-	int pendinginvite;			/*!< Any pending invite ? (seqno of this) */
+	int pendinginvite;			/*!< Any pending INVITE or state NOTIFY (in subscribe pvt's) ? (seqno of this) */
 	struct sip_request initreq;		/*!< Latest request that opened a new transaction
 							within this dialog.
 							NOT the request that opened the dialog
@@ -8752,6 +8753,8 @@ static int transmit_state_notify(struct sip_pvt *p, int state, int full, int tim
 	add_header_contentLength(&req, tmp->used);
 	add_line(&req, tmp->str);
 
+	p->pendinginvite = p->ocseq;	/* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
+
 	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
 }
 
@@ -9992,10 +9995,17 @@ static int cb_extensionstate(char *context, char* exten, int state, void *data)
 		p->laststate = state;
 		break;
 	}
-	if (p->subscribed != NONE)	/* Only send state NOTIFY if we know the format */
-		transmit_state_notify(p, state, 1, FALSE);
-
-	ast_verb(2, "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username);
+	if (p->subscribed != NONE) {	/* Only send state NOTIFY if we know the format */
+		if (!p->pendinginvite) {
+			transmit_state_notify(p, state, 1, FALSE);
+		} else {
+			/* We already have a NOTIFY sent that is not answered. Queue the state up.
+			   if many state changes happen meanwhile, we will only send a notification of the last one */
+			ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
+		}
+	}
+	ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username,
+			ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
 
 	sip_pvt_unlock(p);
 
@@ -14873,6 +14883,10 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
 	else
 		__sip_ack(p, seqno, 0, sipmethod);
 
+	/* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
+	if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 
+		p->pendinginvite = 0;
+
 	/* Get their tag if we haven't already */
 	if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
 		char tag[128];
@@ -14931,6 +14945,11 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
 				} else {
 					if (p->subscribed == NONE) 
 						p->needdestroy = 1;
+					if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
+						/* Ready to send the next state we have on queue */
+						ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
+						cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
+					}
 				}
 			} else if (sipmethod == SIP_REGISTER) 
 				res = handle_response_register(p, resp, rest, req, seqno);