diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h
index 010877441965a05fd62533214f095724ded0f058..f8f7c836b177162161415c29ab9f2effdadb7e8a 100644
--- a/openair2/COMMON/e1ap_messages_types.h
+++ b/openair2/COMMON/e1ap_messages_types.h
@@ -152,8 +152,8 @@ typedef struct pdu_session_to_setup_s {
 } pdu_session_to_setup_t;
 
 typedef struct e1ap_bearer_setup_req_s {
-  uint64_t gNB_cu_cp_ue_id;
-  uint64_t gNB_cu_up_ue_id;
+  uint32_t gNB_cu_cp_ue_id;
+  uint32_t gNB_cu_up_ue_id;
   rnti_t   rnti;
   uint64_t cipheringAlgorithm;
   uint64_t integrityProtectionAlgorithm;
@@ -170,6 +170,13 @@ typedef struct e1ap_bearer_setup_req_s {
   pdu_session_to_setup_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS];
 } e1ap_bearer_setup_req_t;
 
+typedef struct e1ap_bearer_release_cmd_s {
+  uint32_t gNB_cu_cp_ue_id;
+  uint32_t gNB_cu_up_ue_id;
+  long cause_type;
+  long cause;
+} e1ap_bearer_release_cmd_t;
+
 typedef struct drb_setup_s {
   int drbId;
   in_addr_t tlAddress;
diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c
index ab2455a86b4d7060518e6c96e97bcda9f08226ba..f29f8e8153184f51cea62ec6188399b66d934489 100644
--- a/openair2/E1AP/e1ap.c
+++ b/openair2/E1AP/e1ap.c
@@ -51,7 +51,7 @@ e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3] = {
   { e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST, e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE, e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE }, /* bearerContextSetup */
   { e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST, 0, 0 }, /* bearerContextModification */
   { 0, 0, 0 }, /* bearerContextModificationRequired */
-  { 0, 0, 0 }, /* bearerContextRelease */
+  { e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND, e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE, 0 }, /* bearerContextRelease */
   { 0, 0, 0 }, /* bearerContextReleaseRequired */
   { 0, 0, 0 } /* bearerContextInactivityNotification */
 };
@@ -1324,14 +1324,85 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
   BEARER CONTEXT RELEASE
 */
 
-int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance) {
-  AssertFatal(false,"Not implemented yet\n");
-  return -1;
+int fill_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
+                                        e1ap_bearer_release_cmd_t *const cmd,
+                                        E1AP_E1AP_PDU_t *pdu) {
+
+  e1ap_setup_req_t *setup = &getCxtE1(CPtype, instance)->setupReq;
+  if (!setup) {
+    LOG_E(E1AP, "got send_BEARER_CONTEXT_RELEASE_COMMAND on not established instance (%ld)\n", instance);
+    return -1;
+  }
+
+  pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage;
+  asn1cCalloc(pdu->choice.initiatingMessage, msg);
+  msg->procedureCode = E1AP_ProcedureCode_id_bearerContextRelease;
+  msg->criticality   = E1AP_Criticality_reject;
+  msg->value.present = E1AP_InitiatingMessage__value_PR_BearerContextReleaseCommand;
+  E1AP_BearerContextReleaseCommand_t *out = &pdu->choice.initiatingMessage->value.choice.BearerContextReleaseCommand;
+  /* mandatory */
+  /* c1. gNB-CU-CP UE E1AP ID */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextReleaseCommandIEs_t, ieC1);
+  ieC1->id                         = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID;
+  ieC1->criticality                = E1AP_Criticality_reject;
+  ieC1->value.present              = E1AP_BearerContextReleaseCommandIEs__value_PR_GNB_CU_CP_UE_E1AP_ID;
+  ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id;
+  /* mandatory */
+  /* c2. gNB-CU-UP UE E1AP ID */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextReleaseCommandIEs_t, ieC2);
+  ieC2->id                         = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID;
+  ieC2->criticality                = E1AP_Criticality_reject;
+  ieC2->value.present              = E1AP_BearerContextReleaseCommandIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
+  ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id;
+
+  return 0;
 }
 
-int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance) {
-  AssertFatal(false,"Not implemented yet\n");
-  return -1;
+int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
+                                                 e1ap_bearer_release_cmd_t *const cmd) {
+  E1AP_E1AP_PDU_t pdu = {0};
+  fill_BEARER_CONTEXT_RELEASE_COMMAND(instance, cmd, &pdu);
+  return e1ap_encode_send(CPtype, instance, &pdu, 0, __func__);
+}
+
+int fill_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance,
+                                         e1ap_bearer_release_cmd_t *const cmd,
+                                         E1AP_E1AP_PDU_t *pdu) {
+
+  e1ap_setup_req_t *setup = &getCxtE1(CPtype, instance)->setupReq;
+  if (!setup) {
+    LOG_E(E1AP, "got send_BEARER_CONTEXT_RELEASE_COMPLETE on not established instance (%ld)\n", instance);
+    return -1;
+  }
+
+  pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome;
+  asn1cCalloc(pdu->choice.successfulOutcome, msg);
+  msg->procedureCode = E1AP_ProcedureCode_id_bearerContextRelease;
+  msg->criticality   = E1AP_Criticality_reject;
+  msg->value.present = E1AP_SuccessfulOutcome__value_PR_BearerContextReleaseComplete;
+  E1AP_BearerContextReleaseComplete_t *out = &pdu->choice.successfulOutcome->value.choice.BearerContextReleaseComplete;
+  /* mandatory */
+  /* c1. gNB-CU-CP UE E1AP ID */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextReleaseCompleteIEs_t, ieC1);
+  ieC1->id                         = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID;
+  ieC1->criticality                = E1AP_Criticality_reject;
+  ieC1->value.present              = E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_CP_UE_E1AP_ID;
+  ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id;
+  /* mandatory */
+  /* c2. gNB-CU-UP UE E1AP ID */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextReleaseCompleteIEs_t, ieC2);
+  ieC2->id                         = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID;
+  ieC2->criticality                = E1AP_Criticality_reject;
+  ieC2->value.present              = E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
+  ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = cmd->gNB_cu_cp_ue_id;
+
+  return 0;
+}
+
+int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance, e1ap_bearer_release_cmd_t *const cmd) {
+  E1AP_E1AP_PDU_t pdu = {0};
+  fill_BEARER_CONTEXT_RELEASE_COMPLETE(instance, cmd, &pdu);
+  return e1ap_encode_send(CPtype, instance, &pdu, 0, __func__);
 }
 
 int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance) {
@@ -1339,20 +1410,113 @@ int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance) {
   return -1;
 }
 
+void extract_BEARER_CONTEXT_RELEASE_COMMAND(const E1AP_E1AP_PDU_t *pdu,
+                                            e1ap_bearer_release_cmd_t *bearerCxt) {
+  const E1AP_BearerContextReleaseCommand_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextReleaseCommand;
+  E1AP_BearerContextReleaseCommandIEs_t *ie;
+
+  LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count);
+
+  for (int i=0; i < in->protocolIEs.list.count; i++) {
+    ie = in->protocolIEs.list.array[i];
+
+    switch(ie->id) {
+      case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID:
+        DevAssert(ie->criticality == E1AP_Criticality_reject);
+        DevAssert(ie->value.present == E1AP_BearerContextReleaseCommandIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
+        bearerCxt->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID;
+        break;
+
+      case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID:
+        DevAssert(ie->criticality == E1AP_Criticality_reject);
+        DevAssert(ie->value.present == E1AP_BearerContextReleaseCommandIEs__value_PR_GNB_CU_UP_UE_E1AP_ID);
+        bearerCxt->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID;
+        break;
+
+      case E1AP_ProtocolIE_ID_id_Cause:
+        DevAssert(ie->criticality == E1AP_Criticality_ignore);
+        DevAssert(ie->value.present == E1AP_BearerContextReleaseCommandIEs__value_PR_Cause);
+        bearerCxt->cause_type = ie->value.choice.Cause.present;
+        if ((ie->value.choice.Cause.present != E1AP_Cause_PR_NOTHING) &&
+            (ie->value.choice.Cause.present != E1AP_Cause_PR_choice_extension))
+          bearerCxt->cause = ie->value.choice.Cause.choice.radioNetwork;
+
+                                                 
+      default:
+        LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n");
+        break;
+    }
+  }
+}
+
 int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
-                                                   uint32_t assoc_id,
-                                                   uint32_t stream,
-                                                   E1AP_E1AP_PDU_t *pdu) {
-  AssertFatal(false,"Not implemented yet\n");
-  return -1;
+                                                   const E1AP_E1AP_PDU_t *pdu) {
+  e1ap_upcp_inst_t *e1_inst = getCxtE1(UPtype, instance);
+  if (!e1_inst) {
+    LOG_E(E1AP, "got BEARER_CONTEXT_RELEASE_COMMAND on not established instance (%ld)\n", instance);
+    return -1;
+  }
+  
+  DevAssert(pdu != NULL);
+  DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage);
+  DevAssert(pdu->choice.initiatingMessage->procedureCode == E1AP_ProcedureCode_id_bearerContextRelease);
+  DevAssert(pdu->choice.initiatingMessage->criticality == E1AP_Criticality_reject);
+  DevAssert(pdu->choice.initiatingMessage->value.present == E1AP_InitiatingMessage__value_PR_BearerContextReleaseCommand);
+
+  e1ap_bearer_release_cmd_t bearerCxt = {0};
+  extract_BEARER_CONTEXT_RELEASE_COMMAND(pdu, &bearerCxt);
+  CUUP_process_bearer_release_command(&bearerCxt, instance);
+  return 0;
+}
+
+void extract_BEARER_CONTEXT_RELEASE_COMPLETE(const E1AP_E1AP_PDU_t *pdu,
+                                             e1ap_bearer_release_cmd_t *bearerCxt) {
+  const E1AP_BearerContextReleaseComplete_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextReleaseComplete;
+  E1AP_BearerContextReleaseCompleteIEs_t *ie;
+
+  LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count);
+
+  for (int i=0; i < in->protocolIEs.list.count; i++) {
+    ie = in->protocolIEs.list.array[i];
+
+    switch(ie->id) {
+      case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID:
+        DevAssert(ie->criticality == E1AP_Criticality_reject);
+        DevAssert(ie->value.present == E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
+        bearerCxt->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID;
+        break;
+
+      case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID:
+        DevAssert(ie->criticality == E1AP_Criticality_reject);
+        DevAssert(ie->value.present == E1AP_BearerContextReleaseCompleteIEs__value_PR_GNB_CU_UP_UE_E1AP_ID);
+        bearerCxt->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID;
+        break;
+
+      default:
+        LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n");
+        break;
+    }
+  }
 }
 
 int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance,
-                                                    uint32_t assoc_id,
-                                                    uint32_t stream,
-                                                    E1AP_E1AP_PDU_t *pdu) {
-  AssertFatal(false,"Not implemented yet\n");
-  return -1;
+                                                    const E1AP_E1AP_PDU_t *pdu) {
+  e1ap_upcp_inst_t *e1_inst = getCxtE1(UPtype, instance);
+  if (!e1_inst) {
+    LOG_E(E1AP, "got BEARER_CONTEXT_RELEASE_COMPLETE on not established instance (%ld)\n", instance);
+    return -1;
+  }
+  
+  DevAssert(pdu != NULL);
+  DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome);
+  DevAssert(pdu->choice.successfulOutcome->procedureCode == E1AP_ProcedureCode_id_bearerContextRelease);
+  DevAssert(pdu->choice.successfulOutcome->criticality == E1AP_Criticality_reject);
+  DevAssert(pdu->choice.successfulOutcome->value.present == E1AP_SuccessfulOutcome__value_PR_BearerContextReleaseComplete);
+
+  e1ap_bearer_release_cmd_t bearerCxt = {0};
+  extract_BEARER_CONTEXT_RELEASE_COMPLETE(pdu, &bearerCxt);
+  //TODO: CUCP_process_bearer_release_complete(&beareCxt, instance);
+  return 0;
 }
 
 int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance,
diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h
index 96d7ece0bebdba6bbd6c02c244dc40b1df8ec851..7e3abe8fb46c5f60621eba582da668d18d9bc08b 100644
--- a/openair2/E1AP/e1ap.h
+++ b/openair2/E1AP/e1ap.h
@@ -54,6 +54,14 @@ int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
 void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
                                                  e1ap_bearer_setup_resp_t *const resp);
 
+int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
+                                                   const E1AP_E1AP_PDU_t *pdu);
+
+int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance,
+                                                    const E1AP_E1AP_PDU_t *pdu);
+
+int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance, e1ap_bearer_release_cmd_t *const cmd);
+
 void *E1AP_CUUP_task(void *arg);
 
 void *E1AP_CUCP_task(void *arg);
diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c
index e297c6e7777370b535c283e88e14e4047ee26502..37d8e289d326e6cbed92885020c73584cd87209c 100644
--- a/openair2/E1AP/e1ap_api.c
+++ b/openair2/E1AP/e1ap_api.c
@@ -199,3 +199,12 @@ void CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *const req, ins
   // TODO: send bearer cxt mod response
 }
 
+void CUUP_process_bearer_release_command(e1ap_bearer_release_cmd_t *const cmd, instance_t instance) {
+  instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstN3;
+  newGtpuDeleteAllTunnels(gtpInst, cmd->gNB_cu_up_ue_id);
+  gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U;
+  newGtpuDeleteAllTunnels(gtpInst, cmd->gNB_cu_up_ue_id);
+
+  e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(instance, cmd);
+}
+
diff --git a/openair2/E1AP/e1ap_api.h b/openair2/E1AP/e1ap_api.h
index 6f14b1f18dc302c0265f3d579a26b9cf5f2d9121..64cfce44200ecc28869e389e9f438fd04e222833 100644
--- a/openair2/E1AP/e1ap_api.h
+++ b/openair2/E1AP/e1ap_api.h
@@ -31,4 +31,5 @@ void CUUP_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *const req
 
 void CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *const req, instance_t instance);
 
+void CUUP_process_bearer_release_command(e1ap_bearer_release_cmd_t *const cmd, instance_t instance);
 #endif