diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c
index 91d3da474587d233dc0a1da11a90c277e556927c..750bcd02fcf3dc0ae5c247ffdea6d5f3da313d78 100644
--- a/openair3/S1AP/s1ap_eNB_nas_procedures.c
+++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c
@@ -94,10 +94,19 @@ int s1ap_eNB_handle_nas_first_req(
     }
   }
 
+  if (mme_desc_p == NULL) {
+    /* Select MME based on the selected PLMN identity, received through RRC
+     * Connection Setup Complete */
+    mme_desc_p = s1ap_eNB_nnsf_select_mme_by_plmn_id(
+                   instance_p,
+                   s1ap_nas_first_req_p->establishment_cause,
+                   s1ap_nas_first_req_p->selected_plmn_identity);
+  }
+
   if (mme_desc_p == NULL) {
     /*
-     * If no MME corresponds to the GUMMEI or the s-TMSI, selects the MME with the
-     * highest capacity.
+     * If no MME corresponds to the GUMMEI, the s-TMSI, or the selected PLMN
+     * identity, selects the MME with the highest capacity.
      */
     mme_desc_p = s1ap_eNB_nnsf_select_mme(
                    instance_p,
diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c
index 0d5519149c043eeb9e52147a68d4e556b72cc4dd..63dc92b5e260e33c82a3dd076788b4761b1d763c 100644
--- a/openair3/S1AP/s1ap_eNB_nnsf.c
+++ b/openair3/S1AP/s1ap_eNB_nnsf.c
@@ -89,6 +89,76 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t       *instance_p,
   return mme_highest_capacity_p;
 }
 
+struct s1ap_eNB_mme_data_s *
+s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t       *instance_p,
+                                    rrc_establishment_cause_t  cause,
+                                    int                        selected_plmn_identity)
+{
+  struct s1ap_eNB_mme_data_s *mme_data_p = NULL;
+  struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL;
+  uint8_t current_capacity = 0;
+
+  RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
+    struct served_gummei_s *gummei_p = NULL;
+    struct plmn_identity_s *served_plmn_p = NULL;
+    if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) {
+      /* The association between MME and eNB is not ready for the moment,
+       * go to the next known MME.
+       */
+      if (mme_data_p->state == S1AP_ENB_OVERLOAD) {
+        /* MME is overloaded. We have to check the RRC establishment
+         * cause and take decision to the select this MME depending on
+         * the overload state.
+         */
+        if ((cause == RRC_CAUSE_MO_DATA)
+            && (mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_MO_DATA)) {
+          continue;
+        }
+
+        if ((mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_ALL_SIGNALLING)
+            && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA))) {
+          continue;
+        }
+
+        if ((mme_data_p->overload_state == S1AP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
+            && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA)
+                || (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) {
+          continue;
+        }
+
+        /* At this point, the RRC establishment can be handled by the MME
+         * even if it is in overload state.
+         */
+      } else {
+        /* The MME is not overloaded, association is simply not ready. */
+        continue;
+      }
+    }
+
+    /* Looking for served GUMMEI PLMN Identity selected matching the one provided by the UE */
+    STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) {
+      STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) {
+        if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) &&
+            (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) {
+          break;
+        }
+      }
+      /* if found, we can stop the outer loop, too */
+      if (served_plmn_p) break;
+    }
+    /* if we didn't find such a served PLMN, go on with the next MME */
+    if (!served_plmn_p) continue;
+
+    if (current_capacity < mme_data_p->relative_mme_capacity) {
+      /* We find a better MME, keep a reference to it */
+      current_capacity = mme_data_p->relative_mme_capacity;
+      mme_highest_capacity_p = mme_data_p;
+    }
+  }
+
+  return mme_highest_capacity_p;
+}
+
 struct s1ap_eNB_mme_data_s *
 s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t       *instance_p,
                                      rrc_establishment_cause_t  cause,
diff --git a/openair3/S1AP/s1ap_eNB_nnsf.h b/openair3/S1AP/s1ap_eNB_nnsf.h
index 5a3d44416f7219012191c1d5242303deea8eda14..706f3ada6ff8380bf7e94d6a541817eb83064e07 100644
--- a/openair3/S1AP/s1ap_eNB_nnsf.h
+++ b/openair3/S1AP/s1ap_eNB_nnsf.h
@@ -26,6 +26,11 @@ struct s1ap_eNB_mme_data_s *
 s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t       *instance_p,
                          rrc_establishment_cause_t  cause);
 
+struct s1ap_eNB_mme_data_s *
+s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t       *instance_p,
+                                    rrc_establishment_cause_t  cause,
+                                    int                        selected_plmn_identity);
+
 struct s1ap_eNB_mme_data_s*
 s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t       *instance_p,
                                      rrc_establishment_cause_t  cause,