diff --git a/AUTHORS.rst b/AUTHORS.rst
index 3d61c04..7eecd54 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -62,6 +62,7 @@ Ariel Tubaltsev                 atubaltsev@vmware.com
 Arnoldo Lutz                    arnoldo.lutz.guevara@hpe.com
 Arun Sharma                     arun.sharma@calsoftinc.com
 Aryan TaheriMonfared            aryan.taherimonfared@uis.no
+Ashish Varma                    ashishvarma.ovs@gmail.com
 Ashwin Swaminathan              ashwinds@arista.com
 Babu Shanmugam                  bschanmu@redhat.com
 Ben Pfaff                       blp@ovn.org
diff --git a/lib/dpif.c b/lib/dpif.c
index 3233bc8..6b2734b 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -623,6 +623,12 @@ dpif_port_del(struct dpif *dpif, odp_port_t port_no)
     return error;
 }
 
+int
+dpif_port_remove(struct dpif *dpif, odp_port_t port_no)
+{
+    return netdev_ports_remove(port_no, dpif->dpif_class);
+}
+
 /* Makes a deep copy of 'src' into 'dst'. */
 void
 dpif_port_clone(struct dpif_port *dst, const struct dpif_port *src)
diff --git a/lib/dpif.h b/lib/dpif.h
index d9ded8b..c2d1c61 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -452,6 +452,7 @@ const char *dpif_port_open_type(const char *datapath_type,
                                 const char *port_type);
 int dpif_port_add(struct dpif *, struct netdev *, odp_port_t *port_nop);
 int dpif_port_del(struct dpif *, odp_port_t port_no);
+int dpif_port_remove(struct dpif *, odp_port_t port_no);
 
 /* A port within a datapath.
  *
diff --git a/lib/netdev.c b/lib/netdev.c
index 704b38f..954da92 100644
--- a/lib/netdev.c
+++ b/lib/netdev.c
@@ -2179,6 +2179,7 @@ struct ifindex_to_port_data {
     struct hmap_node node;
     int ifindex;
     odp_port_t port;
+    const struct dpif_class *dpif_class;
 };
 
 #define NETDEV_PORTS_HASH_INT(port, dpif) \
@@ -2228,6 +2229,7 @@ netdev_ports_insert(struct netdev *netdev, const struct dpif_class *dpif_class,
     ifidx = xzalloc(sizeof *ifidx);
     ifidx->ifindex = ifindex;
     ifidx->port = dpif_port->port_no;
+    ifidx->dpif_class = dpif_class;
 
     hmap_insert(&port_to_netdev, &data->node, hash);
     hmap_insert(&ifindex_to_port, &ifidx->node, ifidx->ifindex);
@@ -2266,10 +2268,9 @@ netdev_ports_remove(odp_port_t port_no, const struct dpif_class *dpif_class)
 
     if (data) {
         int ifindex = netdev_get_ifindex(data->netdev);
+        struct ifindex_to_port_data *ifidx = NULL;
 
         if (ifindex > 0) {
-            struct ifindex_to_port_data *ifidx = NULL;
-
             HMAP_FOR_EACH_WITH_HASH (ifidx, node, ifindex, &ifindex_to_port) {
                 if (ifidx->port == port_no) {
                     hmap_remove(&ifindex_to_port, &ifidx->node);
@@ -2279,11 +2280,18 @@ netdev_ports_remove(odp_port_t port_no, const struct dpif_class *dpif_class)
             }
             ovs_assert(ifidx);
         } else {
-            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
-
-            VLOG_WARN_RL(&rl, "netdev ports map has dpif port %"PRIu32
-                         " but netdev has no ifindex: %s", port_no,
-                         ovs_strerror(ifindex));
+            /* case where the interface is already deleted form the datapath
+             * (e.g. tunctl -d or ip tuntap del), then the ifindex is not
+             * valid anymore. Traverse the HMAP for the port number. */
+            HMAP_FOR_EACH (ifidx, node, &ifindex_to_port) {
+                if ((ifidx->port == port_no) &&
+                    (ifidx->dpif_class == dpif_class)) {
+                    hmap_remove(&ifindex_to_port, &ifidx->node);
+                    free(ifidx);
+                    break;
+                }
+            }
+            ovs_assert(ifidx);
         }
 
         dpif_port_destroy(&data->dpif_port);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 4bc942d..779aef6 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1923,6 +1923,12 @@ port_destruct(struct ofport *port_, bool del)
         if (!port->is_tunnel) {
             dpif_port_del(ofproto->backer->dpif, port->odp_port);
         }
+    } else if (del) {
+        /* The underlying device is already deleted (e.g. tunctl -d).
+         * Calling dpif_port_remove to do local cleanup for the netdev */
+        if (!port->is_tunnel) {
+            dpif_port_remove(ofproto->backer->dpif, port->odp_port);
+        }
     }
 
     if (port->peer) {
