diff --git a/libnm-util/nm-setting-gsm.c b/libnm-util/nm-setting-gsm.c
index 626d219..19955fb 100644
--- a/libnm-util/nm-setting-gsm.c
+++ b/libnm-util/nm-setting-gsm.c
@@ -80,6 +80,7 @@ typedef struct {
 	guint32 allowed_bands;     /* A bitfield of NM_SETTING_GSM_BAND_* */
 
 	char *pin;
+	char *puk;
 } NMSettingGsmPrivate;
 
 enum {
@@ -187,8 +188,9 @@ nm_setting_gsm_get_pin (NMSettingGsm *setting)
 const char *
 nm_setting_gsm_get_puk (NMSettingGsm *setting)
 {
-	g_warning ("Tried to get deprecated property " NM_SETTING_GSM_SETTING_NAME "/" NM_SETTING_GSM_PUK);
-	return NULL;
+    g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL);
+
+    return NM_SETTING_GSM_GET_PRIVATE (setting)->puk;
 }
 
 static gboolean
@@ -314,7 +316,7 @@ set_property (GObject *object, guint prop_id,
 		    const GValue *value, GParamSpec *pspec)
 {
 	NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE (object);
-	const char *str;
+	/* const char *str; */
 
 	switch (prop_id) {
 	case PROP_NUMBER:
@@ -352,9 +354,8 @@ set_property (GObject *object, guint prop_id,
 		priv->pin = g_value_dup_string (value);
 		break;
 	case PROP_PUK:
-		str = g_value_get_string (value);
-		if (str && strlen (str))
-			g_warning ("Tried to set deprecated property " NM_SETTING_GSM_SETTING_NAME "/" NM_SETTING_GSM_PUK);
+        g_free (priv->puk);
+        priv->puk = g_value_dup_string (value);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -394,8 +395,7 @@ get_property (GObject *object, guint prop_id,
 		g_value_set_string (value, nm_setting_gsm_get_pin (setting));
 		break;
 	case PROP_PUK:
-		/* deprecated */
-		g_value_set_string (value, NULL);
+	    g_value_set_string (value, nm_setting_gsm_get_puk (setting));
 		break;
 	case PROP_BAND:
 		/* deprecated */
diff --git a/src/modem-manager/nm-modem-gsm.c b/src/modem-manager/nm-modem-gsm.c
index 2bd8b23..3a0b5ea 100644
--- a/src/modem-manager/nm-modem-gsm.c
+++ b/src/modem-manager/nm-modem-gsm.c
@@ -168,11 +168,28 @@ stage1_prepare_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_d
 		gboolean retry_secret = FALSE;
 
 		if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PIN))
+		{
 			required_secret = NM_SETTING_GSM_PIN;
-		else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_WRONG)) {
+			retry_secret = FALSE;
+		}
+		else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_PIN_REJECTED))
+		{
+		    required_secret = NM_SETTING_GSM_PIN;
+		    retry_secret = TRUE;
+		}
+		else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_WRONG))
+		{
 			clear_pin (device);
 			required_secret = NM_SETTING_GSM_PIN;
 			retry_secret = TRUE;
+		}
+	    else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PUK)
+	        || dbus_g_error_has_name (error, MM_MODEM_ERROR_PUK_REJECTED)
+	    )
+	    {
+	        required_secret = NM_SETTING_GSM_PUK;
+	        retry_secret = TRUE;
+	        nm_warning ("ask for PUK and new PIN, reason: %s", error->message);
 		} else
 			nm_warning ("GSM modem connection failed: %s", error->message);
 
@@ -217,6 +234,26 @@ create_connect_properties (NMConnection *connection)
 	if (str)
 		value_hash_add_str (properties, "pin", str);
 
+    str = nm_setting_gsm_get_puk (setting);
+    if (str)
+    {
+        /* the PUK/new PIN is returned by the applet as a single string "<PUK>;<New PIN>"*/
+        gchar ** strv = g_strsplit(str, ";", -1);
+        if (strv != NULL)
+        {
+            if (strv[0] != NULL)
+            {
+                value_hash_add_str (properties, "puk", strv[0]);
+                if (strv[1] != NULL)
+                {
+                    value_hash_add_str (properties, "pin", strv[1]);
+                }
+
+            }
+            g_strfreev(strv);
+        }
+    }
+
 	str = nm_setting_gsm_get_username (setting);
 	if (str)
 		value_hash_add_str (properties, "username", str);
diff --git a/src/modem-manager/nm-modem-types.h b/src/modem-manager/nm-modem-types.h
index a251d2a..bf306c5 100644
--- a/src/modem-manager/nm-modem-types.h
+++ b/src/modem-manager/nm-modem-types.h
@@ -29,6 +29,8 @@
 
 #define MM_MODEM_ERROR_GENERAL MM_DBUS_INTERFACE_MODEM ".General"
 #define MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED MM_DBUS_INTERFACE_MODEM ".OperationNotSupported"
+#define MM_MODEM_ERROR_PIN_REJECTED MM_DBUS_INTERFACE_MODEM ".PinRejected"
+#define MM_MODEM_ERROR_PUK_REJECTED MM_DBUS_INTERFACE_MODEM ".PukRejected"
 
 #define MM_MODEM_CONNECT_ERROR_NO_CARRIER MM_DBUS_INTERFACE_MODEM ".NoCarrier"
 #define MM_MODEM_CONNECT_ERROR_NO_DIALTONE MM_DBUS_INTERFACE_MODEM ".NoDialtone"
