diff --git a/include/asterisk/event.h b/include/asterisk/event.h
index ac42e5942733aef29c84485bd8b03b857c734c10..b9de22dd267ba84c059b6d7f24c464bdb83e0cc9 100644
--- a/include/asterisk/event.h
+++ b/include/asterisk/event.h
@@ -156,6 +156,20 @@ void ast_event_sub_destroy(struct ast_event_sub *sub);
 int ast_event_sub_append_ie_uint(struct ast_event_sub *sub,
 	enum ast_event_ie_type ie_type, uint32_t uint);
 
+/*!
+ * \brief Append a bitflags parameter to a subscription
+ *
+ * \param sub the dynamic subscription allocated with ast_event_subscribe_new()
+ * \param ie_type the information element type for the parameter
+ * \param flags the flags that must be present in the event to match this subscription
+ *
+ * \retval 0 success
+ * \retval non-zero failure
+ * \since 1.6.3
+ */
+int ast_event_sub_append_ie_bitflags(struct ast_event_sub *sub,
+	enum ast_event_ie_type ie_type, uint32_t flags);
+
 /*!
  * \brief Append a string parameter to a subscription
  *
@@ -445,6 +459,24 @@ int ast_event_append_ie_str(struct ast_event **event, enum ast_event_ie_type ie_
 int ast_event_append_ie_uint(struct ast_event **event, enum ast_event_ie_type ie_type,
 	uint32_t data);
 
+/*!
+ * \brief Append an information element that has a bitflags payload
+ *
+ * \param event the event that the IE will be appended to
+ * \param ie_type the type of IE to append
+ * \param flags the flags that are the payload of the IE
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ * \since 1.6.3
+ *
+ * The pointer to the event will get updated with the new location for the event
+ * that now contains the appended information element.  If the re-allocation of
+ * the memory for this event fails, it will be set to NULL.
+ */
+int ast_event_append_ie_bitflags(struct ast_event **event, enum ast_event_ie_type ie_type,
+	uint32_t bitflags);
+
 /*!
  * \brief Append an information element that has a raw payload
  *
@@ -475,6 +507,18 @@ int ast_event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_
  */
 uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type);
 
+/*!
+ * \brief Get the value of an information element that has a bitflags payload
+ *
+ * \param event The event to get the IE from
+ * \param ie_type the type of information element to retrieve
+ *
+ * \return This returns the payload of the information element with the given type.
+ *         However, an IE with a payload of 0, and the case where no IE is found
+ *         yield the same return value.
+ */
+uint32_t ast_event_get_ie_bitflags(const struct ast_event *event, enum ast_event_ie_type ie_type);
+
 /*!
  * \brief Get the value of an information element that has a string payload
  *
@@ -614,7 +658,7 @@ int ast_event_iterator_next(struct ast_event_iterator *iterator);
 enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator *iterator);
 
 /*!
- * \brief Get the value of the current IE in the ierator as an integer payload
+ * \brief Get the value of the current IE in the iterator as an integer payload
  *
  * \param iterator The iterator instance
  *
@@ -622,6 +666,15 @@ enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator
  */
 uint32_t ast_event_iterator_get_ie_uint(struct ast_event_iterator *iterator);
 
+/*!
+ * \brief Get the value of the current IE in the iterator as a bitflags payload
+ *
+ * \param iterator The iterator instance
+ *
+ * \return This returns the payload of the information element as bitflags.
+ */
+uint32_t ast_event_iterator_get_ie_bitflags(struct ast_event_iterator *iterator);
+
 /*!
  * \brief Get the value of the current IE in the iterator as a string payload
  *
diff --git a/include/asterisk/event_defs.h b/include/asterisk/event_defs.h
index 3f1e3bd157534f235362c8641326de644256bcff..9bebfb69d2be2044b31001d1ee96c45e05f5e72c 100644
--- a/include/asterisk/event_defs.h
+++ b/include/asterisk/event_defs.h
@@ -137,6 +137,8 @@ enum ast_event_ie_pltype {
 	AST_EVENT_IE_PLTYPE_STR,
 	/*! Raw data, compared with memcmp */
 	AST_EVENT_IE_PLTYPE_RAW,
+	/*! Bit flags (unsigned integer, compared using boolean logic) */
+	AST_EVENT_IE_PLTYPE_BITFLAGS,
 };
 
 /*!
diff --git a/main/event.c b/main/event.c
index bc814720d75d5038a69f4578d30efd31cd48ce11..483d478324a80f254700df0ca86a063a9b9f2358 100644
--- a/main/event.c
+++ b/main/event.c
@@ -311,6 +311,7 @@ static void ast_event_ie_val_destroy(struct ast_event_ie_val *ie_val)
 		ast_free(ie_val->payload.raw);
 		break;
 	case AST_EVENT_IE_PLTYPE_UINT:
+	case AST_EVENT_IE_PLTYPE_BITFLAGS:
 	case AST_EVENT_IE_PLTYPE_EXISTS:
 	case AST_EVENT_IE_PLTYPE_UNKNOWN:
 		break;
@@ -347,6 +348,9 @@ enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type typ
 		case AST_EVENT_IE_PLTYPE_UINT:
 			ie_value->payload.uint = va_arg(ap, uint32_t);
 			break;
+		case AST_EVENT_IE_PLTYPE_BITFLAGS:
+			ie_value->payload.uint = va_arg(ap, uint32_t);
+			break;
 		case AST_EVENT_IE_PLTYPE_STR:
 			ie_value->payload.str = va_arg(ap, const char *);
 			break;
@@ -392,6 +396,12 @@ enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type typ
 			case AST_EVENT_IE_PLTYPE_UINT:
 				break_out = (ie_val->payload.uint != sub_ie_val->payload.uint);
 				break;
+			case AST_EVENT_IE_PLTYPE_BITFLAGS:
+				/* if the subscriber has requested *any* of the bitflags we are providing,
+				 * then it's a match
+				 */
+				break_out = (ie_val->payload.uint & sub_ie_val->payload.uint);
+				break;
 			case AST_EVENT_IE_PLTYPE_STR:
 				break_out = strcmp(ie_val->payload.str, sub_ie_val->payload.str);
 				break;
@@ -436,14 +446,26 @@ enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type typ
 static int match_ie_val(const struct ast_event *event,
 		const struct ast_event_ie_val *ie_val, const struct ast_event *event2)
 {
-	if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_UINT) {
+	switch (ie_val->ie_pltype) {
+	case AST_EVENT_IE_PLTYPE_UINT:
+	{
 		uint32_t val = event2 ? ast_event_get_ie_uint(event2, ie_val->ie_type) : ie_val->payload.uint;
-		if (val == ast_event_get_ie_uint(event, ie_val->ie_type))
-			return 1;
-		return 0;
+
+		return (val == ast_event_get_ie_uint(event, ie_val->ie_type)) ? 1 : 0;
+	}
+
+	case AST_EVENT_IE_PLTYPE_BITFLAGS:
+	{
+		uint32_t flags = event2 ? ast_event_get_ie_uint(event2, ie_val->ie_type) : ie_val->payload.uint;
+
+		/* if the subscriber has requested *any* of the bitflags that this event provides,
+		 * then it's a match
+		 */
+		return (flags & ast_event_get_ie_bitflags(event, ie_val->ie_type)) ? 1 : 0;
 	}
 
-	if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_STR) {
+	case AST_EVENT_IE_PLTYPE_STR:
+	{
 		const char *str;
 		uint32_t hash;
 
@@ -460,16 +482,19 @@ static int match_ie_val(const struct ast_event *event,
 		return 0;
 	}
 
-	if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_RAW) {
+	case AST_EVENT_IE_PLTYPE_RAW:
+	{
 		const void *buf = event2 ? ast_event_get_ie_raw(event2, ie_val->ie_type) : ie_val->payload.raw;
-		if (buf && !memcmp(buf, ast_event_get_ie_raw(event, ie_val->ie_type), ie_val->raw_datalen))
-			return 1;
-		return 0;
+
+		return (buf && !memcmp(buf, ast_event_get_ie_raw(event, ie_val->ie_type), ie_val->raw_datalen)) ? 1 : 0;
 	}
 
-	if (ie_val->ie_pltype == AST_EVENT_IE_PLTYPE_EXISTS) {
-		if (ast_event_get_ie_raw(event, ie_val->ie_type))
-			return 1;
+	case AST_EVENT_IE_PLTYPE_EXISTS:
+	{
+		return ast_event_get_ie_raw(event, ie_val->ie_type) ? 1 : 0;
+	}
+
+	case AST_EVENT_IE_PLTYPE_UNKNOWN:
 		return 0;
 	}
 
@@ -527,6 +552,9 @@ static struct ast_event *gen_sub_event(struct ast_event_sub *sub)
 		case AST_EVENT_IE_PLTYPE_UINT:
 			ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
 			break;
+		case AST_EVENT_IE_PLTYPE_BITFLAGS:
+			ast_event_append_ie_bitflags(&event, ie_val->ie_type, ie_val->payload.uint);
+			break;
 		case AST_EVENT_IE_PLTYPE_STR:
 			ast_event_append_ie_str(&event, ie_val->ie_type, ie_val->payload.str);
 			break;
@@ -625,6 +653,26 @@ int ast_event_sub_append_ie_uint(struct ast_event_sub *sub,
 	return 0;
 }
 
+int ast_event_sub_append_ie_bitflags(struct ast_event_sub *sub,
+	enum ast_event_ie_type ie_type, uint32_t flags)
+{
+	struct ast_event_ie_val *ie_val;
+
+	if (ie_type < 0 || ie_type > AST_EVENT_IE_MAX)
+		return -1;
+
+	if (!(ie_val = ast_calloc(1, sizeof(*ie_val))))
+		return -1;
+
+	ie_val->ie_type = ie_type;
+	ie_val->payload.uint = flags;
+	ie_val->ie_pltype = AST_EVENT_IE_PLTYPE_BITFLAGS;
+
+	AST_LIST_INSERT_TAIL(&sub->ie_vals, ie_val, entry);
+
+	return 0;
+}
+
 int ast_event_sub_append_ie_exists(struct ast_event_sub *sub,
 	enum ast_event_ie_type ie_type)
 {
@@ -753,6 +801,12 @@ struct ast_event_sub *ast_event_subscribe(enum ast_event_type type, ast_event_cb
 			ast_event_sub_append_ie_uint(sub, ie_type, unsigned_int);
 			break;
 		}
+		case AST_EVENT_IE_PLTYPE_BITFLAGS:
+		{
+			uint32_t unsigned_int = va_arg(ap, uint32_t);
+			ast_event_sub_append_ie_bitflags(sub, ie_type, unsigned_int);
+			break;
+		}
 		case AST_EVENT_IE_PLTYPE_STR:
 		{
 			const char *str = va_arg(ap, const char *);
@@ -839,6 +893,11 @@ uint32_t ast_event_iterator_get_ie_uint(struct ast_event_iterator *iterator)
 	return ntohl(get_unaligned_uint32(iterator->ie->ie_payload));
 }
 
+uint32_t ast_event_iterator_get_ie_bitflags(struct ast_event_iterator *iterator)
+{
+	return ntohl(get_unaligned_uint32(iterator->ie->ie_payload));
+}
+
 const char *ast_event_iterator_get_ie_str(struct ast_event_iterator *iterator)
 {
 	const struct ast_event_ie_str_payload *str_payload;
@@ -867,6 +926,15 @@ uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_
 	return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0;
 }
 
+uint32_t ast_event_get_ie_bitflags(const struct ast_event *event, enum ast_event_ie_type ie_type)
+{
+	const uint32_t *ie_val;
+
+	ie_val = ast_event_get_ie_raw(event, ie_type);
+
+	return ie_val ? ntohl(get_unaligned_uint32(ie_val)) : 0;
+}
+
 uint32_t ast_event_get_ie_str_hash(const struct ast_event *event, enum ast_event_ie_type ie_type)
 {
 	const struct ast_event_ie_str_payload *str_payload;
@@ -921,6 +989,13 @@ int ast_event_append_ie_uint(struct ast_event **event, enum ast_event_ie_type ie
 	return ast_event_append_ie_raw(event, ie_type, &data, sizeof(data));
 }
 
+int ast_event_append_ie_bitflags(struct ast_event **event, enum ast_event_ie_type ie_type,
+	uint32_t flags)
+{
+	flags = htonl(flags);
+	return ast_event_append_ie_raw(event, ie_type, &flags, sizeof(flags));
+}
+
 int ast_event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_type,
 	const void *data, size_t data_len)
 {
@@ -974,6 +1049,9 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...)
 		case AST_EVENT_IE_PLTYPE_UINT:
 			ie_value->payload.uint = va_arg(ap, uint32_t);
 			break;
+		case AST_EVENT_IE_PLTYPE_BITFLAGS:
+			ie_value->payload.uint = va_arg(ap, uint32_t);
+			break;
 		case AST_EVENT_IE_PLTYPE_STR:
 			ie_value->payload.str = va_arg(ap, const char *);
 			break;
@@ -1014,6 +1092,9 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...)
 		case AST_EVENT_IE_PLTYPE_UINT:
 			ast_event_append_ie_uint(&event, ie_val->ie_type, ie_val->payload.uint);
 			break;
+		case AST_EVENT_IE_PLTYPE_BITFLAGS:
+			ast_event_append_ie_bitflags(&event, ie_val->ie_type, ie_val->payload.uint);
+			break;
 		case AST_EVENT_IE_PLTYPE_RAW:
 			ast_event_append_ie_raw(&event, ie_val->ie_type,
 					ie_val->payload.raw, ie_val->raw_datalen);
@@ -1108,6 +1189,9 @@ struct ast_event *ast_event_get_cached(enum ast_event_type type, ...)
 		case AST_EVENT_IE_PLTYPE_UINT:
 			ast_event_append_ie_uint(&cache_arg_event, ie_type, va_arg(ap, uint32_t));
 			break;
+		case AST_EVENT_IE_PLTYPE_BITFLAGS:
+			ast_event_append_ie_bitflags(&cache_arg_event, ie_type, va_arg(ap, uint32_t));
+			break;
 		case AST_EVENT_IE_PLTYPE_STR:
 			ast_event_append_ie_str(&cache_arg_event, ie_type, va_arg(ap, const char *));
 			break;