diff --git a/ci-scripts/conf_files/gNB_SA_CU.conf b/ci-scripts/conf_files/gNB_SA_CU.conf
index 27b079d02694bb031456b3edcfaeaf380650c226..14bf78a43a1dad89d949b28693b3cbb875c9fdbc 100644
--- a/ci-scripts/conf_files/gNB_SA_CU.conf
+++ b/ci-scripts/conf_files/gNB_SA_CU.conf
@@ -182,6 +182,17 @@ gNBs =
                             }
                           );
 
+    E1_INTERFACE:
+    (
+      {
+        type = "cu";
+        ipv4_cucp = "192.168.100.1";
+        port_cucp = 25;
+        ipv4_cuup = "192.168.100.2";
+        port_cuup = 25;
+      }
+    )
+
     NETWORK_INTERFACES :
     {
 
diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c
index bb41c94d3df6a745c514ca9fe56f5a38bb14c8f1..ea1d74a3f7ad1eb8e74cd9c7f18f871da3c61f27 100644
--- a/openair2/E1AP/e1ap.c
+++ b/openair2/E1AP/e1ap.c
@@ -1085,6 +1085,55 @@ void cuup_task_handle_sctp_association_resp(instance_t instance, sctp_new_associ
   e1apCUUP_send_SETUP_REQUEST(instance);
 }
 
+void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr) {
+  LOG_I(E1AP, "E1AP_CUCP_SCTP_REQ(create socket)\n");
+  MessageDef  *message_p = NULL;
+  message_p = itti_alloc_new_message (TASK_CUCP_E1, 0, SCTP_INIT_MSG);
+  message_p->ittiMsg.sctp_init.port = E1AP_PORT_NUMBER;
+  message_p->ittiMsg.sctp_init.ppid = E1AP_SCTP_PPID;
+  message_p->ittiMsg.sctp_init.ipv4 = 1;
+  message_p->ittiMsg.sctp_init.ipv6 = 0;
+  message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
+  message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(my_addr);
+  /*
+   * SR WARNING: ipv6 multi-homing fails sometimes for localhost.
+   * * * * Disable it for now.
+   */
+  message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
+  message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
+  itti_send_msg_to_task(TASK_SCTP, instance, message_p);
+}
+
+void *E1AP_CUCP_task(void *arg) {
+  LOG_I(E1AP, "Starting E1AP at CU CP\n");
+  MessageDef *msg = NULL;
+  int         result;
+
+  while (1) {
+    itti_receive_msg(TASK_CUCP_E1, &msg);
+
+    switch (ITTI_MSG_ID(msg)) {
+      case E1AP_SETUP_REQ:
+        LOG_I(E1AP, "CUCP Task Received E1AP_SETUP_REQ for instance %ld. Initializing SCTP listener\n",
+              ITTI_MSG_DESTINATION_INSTANCE(msg));
+        e1ap_setup_req_t *req = &E1AP_SETUP_REQ(msg);
+        char *ipaddr;
+        if (req->CUCP_e1_ip_address.ipv4 == 0) {
+          LOG_E(E1AP, "No IPv4 address configured\n");
+          return -1;
+        }
+        else
+          ipaddr = req->CUCP_e1_ip_address.ipv4_address;
+        cucp_task_send_sctp_init_req(0, ipaddr);
+        break;
+
+      default:
+        LOG_E(E1AP, "Unknown message received in TASK_CUCP_E1\n");
+        break;
+    }
+  }
+}
+
 void *E1AP_CUUP_task(void *arg) {
   LOG_I(E1AP, "Starting E1AP at CU UP\n");
 
@@ -1112,6 +1161,10 @@ void *E1AP_CUUP_task(void *arg) {
         LOG_I(E1AP, "CUUP Task Received SCTP_DATA_IND\n");
         cuup_task_handle_sctp_data_ind(instance, &msg->ittiMsg.sctp_data_ind);
         break;
+
+      default:
+        LOG_E(E1AP, "Unknown message received in TASK_CUUP_E1\n");
+        break;
     }
   }
 }
diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h
index d05fc15129a08dd61bc5e853b5a8835c83b6b6d2..cf61b0fbecbdda6ae84ebf1e40e94784099106c8 100644
--- a/openair2/E1AP/e1ap_common.h
+++ b/openair2/E1AP/e1ap_common.h
@@ -30,6 +30,9 @@
 #define E1AP_SETUP_REQ(mSGpTR)                     (mSGpTR)->ittiMsg.e1ap_setup_req
 #define E1AP_SETUP_RESP(mSGpTR)                    (mSGpTR)->ittiMsg.e1ap_setup_resp
 
+#define E1AP_PORT_NUMBER 25
+#define E1AP_SCTP_PPID 63
+
 typedef f1ap_net_ip_address_t e1ap_net_ip_address_t;
 
 typedef int (*e1ap_message_processing_t)(
@@ -49,7 +52,6 @@ typedef struct e1ap_setup_req_s {
   uint64_t              gNB_cu_up_id;
   char *                gNB_cu_up_name;
   uint64_t              transac_id;
-  uint64_t              cn_support;
   int                   supported_plmns; 
   PLMN_ID_t             plmns[E1AP_MAX_NUM_PLMNS];
   uint16_t              sctp_in_streams;
diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c
index 821e2def84afca4c56a60feffaef75f987423c9c..2965a6c29b77edb03bfae40c9c7dc0dcf53dd64e 100644
--- a/openair2/GNB_APP/gnb_app.c
+++ b/openair2/GNB_APP/gnb_app.c
@@ -67,6 +67,7 @@ static void configure_nr_rrc(uint32_t gnb_id)
   msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ);
 
   if (RC.nrrrc[gnb_id]) {
+    set_node_type();
     RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]);
     
     LOG_I(GNB_APP, "RRC starting with node type %d\n", RC.nrrrc[gnb_id]->node_type);
@@ -200,6 +201,30 @@ void *gNB_app_task(void *args_p)
           LOG_E(F1AP, "Create task for F1AP CU failed\n");
           AssertFatal(1==0,"exiting");
       }
+
+      if (RC.nrrrc[0]->cu_type == CPtype) {
+        if (itti_create_task(TASK_CUCP_E1, E1AP_CUCP_task, NULL) < 0) {
+          LOG_E(E1AP, "Create task for E1AP CP failed\n");
+          AssertFatal(1==0, "exiting");
+        }
+        // To initialize SCTP listener
+        msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ);
+        RCconfig_NR_CU_E1(msg_p, 0);
+
+        itti_send_msg_to_task(TASK_CUCP_E1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
+      } else if (RC.nrrrc[0]->cu_type == UPtype) {
+        if (itti_create_task(TASK_CUUP_E1, E1AP_CUUP_task, NULL) < 0) {
+          LOG_E(E1AP, "Create task for E1AP UP failed\n");
+          AssertFatal(1==0, "exiting");
+        }
+        // configure E1AP here
+        LOG_I(GNB_APP, "ngran_gNB_CU: Allocating ITTI message for E1AP_SETUP_REQ\n");
+        msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ);
+        RCconfig_NR_CU_E1(msg_p, 0);
+
+        itti_send_msg_to_task(TASK_CUUP_E1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
+      }
+
     }
 
     if (NODE_IS_DU(RC.nrrrc[0]->node_type)) {
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 25df321b3a7d024fbcc68fb6a935657e1b24f642..9ffd3e2f3aa13b4d7e8bc27276f165f3d7e9cefa 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -1166,21 +1166,13 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
       rrc->eth_params_s.my_portd                 = *(GNBParamList.paramarray[i][GNB_LOCAL_S_PORTD_IDX].uptr);
       rrc->eth_params_s.remote_portd             = *(GNBParamList.paramarray[i][GNB_REMOTE_S_PORTD_IDX].uptr);
       rrc->eth_params_s.transp_preference        = ETH_UDP_MODE;
-      rrc->node_type                             = ngran_gNB_CU;
       rrc->sctp_in_streams                       = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
       rrc->sctp_out_streams                      = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr);
-    } else {
-      // set to ngran_gNB for now, it will get set to ngran_gNB_DU if macrlc entity which uses F1 is present
-      // Note: we will have to handle the case of ngran_ng_gNB_DU
-      if (macrlc_has_f1 == 0) {
-        rrc->node_type = ngran_gNB;
-        LOG_I(NR_RRC,"Setting node_type to ngran_gNB\n");
-      } else {
-        rrc->node_type = ngran_gNB_DU;
-        LOG_I(NR_RRC,"Setting node_type to ngran_gNB_DU\n");
-      }
     }
 
+    rrc->node_type = node_type;
+    rrc->cu_type = cu_type;
+
     rrc->nr_cellid        = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr);
 
     rrc->um_on_default_drb = *(GNBParamList.paramarray[i][GNB_UMONDEFAULTDRB_IDX].uptr);
@@ -1836,6 +1828,54 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
   return 0;
 }
 
+int RCconfig_NR_CU_E1(MessageDef *msg_p, uint32_t i) {
+  paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
+  paramdef_t GNBParams[]  = GNBPARAMS_DESC;
+  paramdef_t GNBE1Params[] = GNBE1PARAMS_DESC;
+  paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
+  paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0};
+  config_get(GNBSParams, sizeof(GNBSParams)/sizeof(paramdef_t), NULL);
+  int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
+  AssertFatal (i < num_gnbs,
+               "Failed to parse config file no %uth element in %s \n",i, GNB_CONFIG_STRING_ACTIVE_GNBS);
+
+  if (num_gnbs > 0) {
+    config_getlist(&GNBParamList, GNBParams, sizeof(GNBParams)/sizeof(paramdef_t), NULL);
+    AssertFatal(GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr != NULL,
+                "gNB id %u is not defined in configuration file\n",i);
+    config_getlist(&GNBE1ParamList, GNBE1Params, sizeof(GNBE1Params)/sizeof(paramdef_t), NULL);
+    e1ap_setup_req_t *e1Setup = &E1AP_SETUP_REQ(msg_p);
+    e1setup->gNB_cu_up_id = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr);
+
+    paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC;
+    paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0};
+    /* map parameter checking array instances to parameter definition array instances */
+    checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
+
+    for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
+      PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
+
+    config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
+    int numPLMNs = PLMNParamList.numelt;
+    e1Setup->supported_plmns = numPLMNs;
+
+    for (int I = 0; I < numPLMNs; I++) {
+      e1Setup->plmns[I].mcc = *PLMNParamList.paramarray[I][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
+      e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MOBILE_NETWORK_CODE_IDX].uptr;
+      e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MNC_DIGIT_LENGTH].u8ptr;
+    }
+
+    strcpy(e1Setup->CUCP_e1_ip_address.ipv4_address, GNBE1PARAMList.paramarray[0][GNB_CONFIG_E1_IPV4_ADDRESS_CUCP].strptr);
+    e1Setup->port_cucp = *GNBE1PARAMList.paramarray[0][GNB_CONFIG_E1_PORT_CUCP].uptr;
+    strcpy(e1Setup->CUUP_e1_ip_address.ipv4_address, GNBE1PARAMList.paramarray[0][GNB_CONFIG_E1_IPV4_ADDRESS_CUUP].strptr);
+    e1Setup->port_cuup = *GNBE1PARAMList.paramarray[0][GNB_CONFIG_E1_PORT_CUUP].uptr;
+
+    e1Setup->cn_support = *GNBE1PARAMList.Paramarray[0][GNB_CONFIG_E1_CN_SUPPORT].uptr;
+  }
+
+  return 0;
+}
+
 int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) {
   int k;
   paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
@@ -2269,9 +2309,12 @@ static ngran_node_t get_node_type(void)
   paramlist_def_t   MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
   paramdef_t        GNBParams[]  = GNBPARAMS_DESC;
   paramlist_def_t   GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
+  paramdef_t        GNBE1Params[] = GNBE1PARAMS_DESC;
+  paramlist_def_t   GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0};
 
   config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL);   
   config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);  
+  config_getlist( &GNBE1ParamList, GNBE1Params, sizeof(GNBE1Params)/sizeof(paramdef_t), NULL);
 
   if ( MacRLC_ParamList.numelt > 0) {
     RC.nb_nr_macrlc_inst = MacRLC_ParamList.numelt; 
@@ -2282,7 +2325,8 @@ static ngran_node_t get_node_type(void)
     }
   }
 
-  if (strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0)
+  if ((strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) &&
+      (strcmp(*(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CU_TYPE_IDX].strptr), "cu") == 0))
     return ngran_gNB_CU;
   else if (macrlc_has_f1 == 0)
     return ngran_gNB;
diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h
index 9572d16d8f4c1fce65fee032bf6752b60d6bfdb4..13197fa39e5edd3a9a448b3df4a16166cd96e39b 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -365,6 +365,32 @@ typedef enum {
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 
+/* E1 configuration section */
+#define GNB_CONFIG_STRING_E1_PARAMETERS                   "E1_INTERFACE"
+
+#define GNB_CONFIG_E1_CU_TYPE_IDX                         0
+#define GNB_CONFIG_E1_IPV4_ADDRESS_CUCP                   1
+#define GNB_CONFIG_E1_PORT_CUCP                           2
+#define GNB_CONFIG_E1_IPV4_ADDRESS_CUUP                   3
+#define GNB_CONFIG_E1_PORT_CUUP                           4
+#define GNB_CONFIG_E1_CN_SUPPORT                          5
+
+#define GNB_CONFIG_STRING_E1_CU_TYPE                      "type"
+#define GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUCP            "ipv4_cucp"
+#define GNB_CONFIG_STRING_E1_PORT_CUCP                    "port_cucp"
+#define GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUUP            "ipv4_cuup"
+#define GNB_CONFIG_STRING_E1_PORT_CUUP                    "port_cuup"
+#define GNB_CONFIG_STRING_E1_CN_SUPPORT                   "cn_support"
+
+#define GNBE1PARAMS_DESC { \
+  {GNB_CONFIG_STRING_E1_CU_TYPE,           NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
+  {GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUCP, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
+  {GNB_CONFIG_STRING_E1_PORT_CUCP,         NULL, 0, uptr  :NULL, defintval:25L,  TYPE_UINT,   0}, \
+  {GNB_CONFIG_STRING_E1_IPV4_ADDRESS_CUUP, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
+  {GNB_CONFIG_STRING_E1_PORT_CUUP,         NULL, 0, uptr  :NULL, defintval:25L,  TYPE_UINT,   0} \
+  {GNB_CONFIG_STRING_E1_CN_SUPPORT,        NULL, 0, uptr  :NULL, defintval:1L,   TYPE_UNIT,   0} \
+}
+
 /* L1 configuration section names   */
 #define CONFIG_STRING_L1_LIST                              "L1s"
 #define CONFIG_STRING_L1_CONFIG                            "l1_config"