diff --git a/openair2/ENB_APP/enb_agent_common.c b/openair2/ENB_APP/enb_agent_common.c
index 51d7161b586e7472f1a3e030aade39a17ed7172a..1e7efe920ac21405182c31d899f1c4ae5e156d65 100644
--- a/openair2/ENB_APP/enb_agent_common.c
+++ b/openair2/ENB_APP/enb_agent_common.c
@@ -604,13 +604,80 @@ int enb_agent_destroy_lc_config_reply(Protocol__ProgranMessage *msg) {
 }
 
 int enb_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change) {
-  /* TODO: Create a progRAN message with the state changes requested for the UE with RNTI rnti */
-  return 0;
+  int size;
+  Protocol__ProgranMessage *msg;
+  Protocol__PrpHeader *header;
+  void *data;
+  int priority;
+  err_code_t err_code;
+
+  int xid = 0;
+
+  if (prp_create_header(xid, PROTOCOL__PRP_TYPE__PRPT_UE_STATE_CHANGE, &header) != 0)
+    goto error;
+
+  Protocol__PrpUeStateChange *ue_state_change_msg;
+  ue_state_change_msg = malloc(sizeof(Protocol__PrpUeStateChange));
+  if(ue_state_change_msg == NULL) {
+    goto error;
+  }
+  protocol__prp_ue_state_change__init(ue_state_change_msg);
+  ue_state_change_msg->has_type = 1;
+  ue_state_change_msg->type = state_change;
+
+  Protocol__PrpUeConfig *config;
+  config = malloc(sizeof(Protocol__PrpUeConfig));
+  if (config == NULL) {
+    goto error;
+  }
+  protocol__prp_ue_config__init(config);
+  if (state_change == PROTOCOL__PRP_UE_STATE_CHANGE_TYPE__PRUESC_DEACTIVATED) {
+    // Simply set the rnti of the UE
+    config->has_rnti = 1;
+    config->rnti = rnti;
+  } else if (state_change == PROTOCOL__PRP_UE_STATE_CHANGE_TYPE__PRUESC_UPDATED
+	     || state_change == PROTOCOL__PRP_UE_STATE_CHANGE_TYPE__PRUESC_ACTIVATED) {
+    // TODO: Set the whole UE configuration message
+    
+  } else if (state_change == PROTOCOL__PRP_UE_STATE_CHANGE_TYPE__PRUESC_MOVED) {
+    // TODO: Not supported for now. Leave blank
+  }
+
+  ue_state_change_msg->config = config;
+  msg = malloc(sizeof(Protocol__ProgranMessage));
+  if (msg == NULL) {
+    goto error;
+  }
+  protocol__progran_message__init(msg);
+  msg->msg_case = PROTOCOL__PROGRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG;
+  msg->msg_dir = PROTOCOL__PROGRAN_DIRECTION__INITIATING_MESSAGE;
+  msg->ue_state_change_msg = ue_state_change_msg;
+  
+  data = enb_agent_pack_message(msg, &size);
+  /*Send sr info using the MAC channel of the eNB*/
+  if (enb_agent_msg_send(mod_id, ENB_AGENT_DEFAULT, data, size, priority)) {
+    err_code = PROTOCOL__PROGRAN_ERR__MSG_ENQUEUING;
+    goto error;
+  }
+
+  LOG_D(ENB_AGENT,"sent message with size %d\n", size);
+  return;
+ error:
+  LOG_D(ENB_AGENT, "Could not send UE state message\n");
 }
 
 int enb_agent_destroy_ue_state_change(Protocol__ProgranMessage *msg) {
-  /* TODO: Dealocate memory for a dynamically allocated UE state change message */
+  if(msg->msg_case != PROTOCOL__PROGRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG)
+    goto error;
+  free(msg->ue_state_change_msg->header);
+  //TODO: Free the contents of the UE config structure
+  free(msg->ue_state_change_msg);
+  free(msg);
   return 0;
+
+ error:
+  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+  return -1;
 }
 
 int enb_agent_destroy_enb_config_request(Protocol__ProgranMessage *msg) {
diff --git a/openair2/ENB_APP/enb_agent_mac.c b/openair2/ENB_APP/enb_agent_mac.c
index f31da89d811588f11dcf921e70df1e5377db537a..5c279958fed4c8119709236064ffa5e2a040170a 100644
--- a/openair2/ENB_APP/enb_agent_mac.c
+++ b/openair2/ENB_APP/enb_agent_mac.c
@@ -1266,7 +1266,7 @@ int enb_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
   xface->enb_agent_send_sf_trigger = enb_agent_send_sf_trigger;
   xface->enb_agent_send_update_mac_stats = enb_agent_send_update_mac_stats;
   xface->enb_agent_schedule_ue_spec = schedule_ue_spec_default;
-
+  xface->enb_agent_notify_ue_state_change = enb_agent_ue_state_change;
 
   mac_agent_registered[mod_id] = 1;
   agent_mac_xface[mod_id] = xface;
diff --git a/openair2/ENB_APP/enb_agent_mac_defs.h b/openair2/ENB_APP/enb_agent_mac_defs.h
index 6e960cdb698743916cd3f3182f05fc9ef2df1006..657fc94fe4380eb2a53d21864a2afad3c6fe2059 100644
--- a/openair2/ENB_APP/enb_agent_mac_defs.h
+++ b/openair2/ENB_APP/enb_agent_mac_defs.h
@@ -62,6 +62,12 @@ typedef struct {
   void (*enb_agent_schedule_ue_spec)(mid_t mod_id, uint32_t frame, uint32_t subframe,
 				     int *mbsfn_flag, Protocol__ProgranMessage *dl_info);
 
+
+  /// Notify the controller for a state change of a particular UE, by sending the proper
+  /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER)
+  void (*enb_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti,
+					   uint32_t state_change);
+  
   /*TODO: Fill in with the rest of the MAC layer technology specific callbacks (UL/DL scheduling, RACH info etc)*/
 
 } AGENT_MAC_xface;