diff --git a/controller/binding.c b/controller/binding.c
index db1eb7a40..5df62baef 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -1873,6 +1873,7 @@ build_local_bindings(struct binding_ctx_in *b_ctx_in,
                     lbinding = local_binding_create(iface_id, iface_rec);
                     local_binding_add(local_bindings, lbinding);
                 } else {
+                    lbinding->multiple_bindings = true;
                     static struct vlog_rate_limit rl =
                         VLOG_RATE_LIMIT_INIT(1, 5);
                     VLOG_WARN_RL(
@@ -2163,6 +2164,10 @@ consider_iface_claim(const struct ovsrec_interface *iface_rec,
         lbinding = local_binding_create(iface_id, iface_rec);
         local_binding_add(local_bindings, lbinding);
     } else {
+        if (lbinding->iface && lbinding->iface != iface_rec) {
+            lbinding->multiple_bindings = true;
+            b_ctx_out->local_lports_changed = true;
+        }
         lbinding->iface = iface_rec;
     }
 
@@ -2181,6 +2186,13 @@ consider_iface_claim(const struct ovsrec_interface *iface_rec,
         return true;
     }
 
+    /* If multiple bindings to the same port, remove the "old" binding.
+     * This ensures that change tracking is correct.
+     */
+    if (lbinding->multiple_bindings) {
+        remove_related_lport(pb, b_ctx_out);
+    }
+
     enum en_lport_type lport_type = get_lport_type(pb);
     if (lport_type == LP_LOCALPORT) {
         return consider_localport(pb, b_ctx_in, b_ctx_out);
@@ -2235,18 +2247,24 @@ consider_iface_release(const struct ovsrec_interface *iface_rec,
     lbinding = local_binding_find(local_bindings, iface_id);
 
    if (lbinding) {
-        int64_t ofport = iface_rec->n_ofport ? *iface_rec->ofport : 0;
-        if (lbinding->iface != iface_rec && !ofport) {
-            /* If external_ids:iface-id is set within the same transaction
-             * as adding an interface to a bridge, ovn-controller is
-             * usually initially notified of ovs interface changes with
-             * ofport == 0. If the lport was bound to a different interface
-             * we do not want to release it.
-             */
-            VLOG_DBG("Not releasing lport %s as %s was claimed "
-                     "and %s was never bound)", iface_id, lbinding->iface ?
-                     lbinding->iface->name : "", iface_rec->name);
-            return true;
+        if (lbinding->multiple_bindings) {
+            VLOG_INFO("Multiple bindings for %s: force recompute to clean up",
+                      iface_id);
+            return false;
+        } else {
+            int64_t ofport = iface_rec->n_ofport ? *iface_rec->ofport : 0;
+            if (lbinding->iface != iface_rec && !ofport) {
+                /* If external_ids:iface-id is set within the same transaction
+                 * as adding an interface to a bridge, ovn-controller is
+                 * usually initially notified of ovs interface changes with
+                 * ofport == 0. If the lport was bound to a different interface
+                 * we do not want to release it.
+                 */
+                VLOG_DBG("Not releasing lport %s as %s was claimed "
+                         "and %s was never bound)", iface_id, lbinding->iface ?
+                         lbinding->iface->name : "", iface_rec->name);
+                return true;
+            }
         }
     }
 
@@ -3058,6 +3076,7 @@ local_binding_create(const char *name, const struct ovsrec_interface *iface)
     struct local_binding *lbinding = xzalloc(sizeof *lbinding);
     lbinding->name = xstrdup(name);
     lbinding->iface = iface;
+    lbinding->multiple_bindings = false;
     ovs_list_init(&lbinding->binding_lports);
 
     return lbinding;
diff --git a/controller/binding.h b/controller/binding.h
index ad959a9e6..6c3a98b02 100644
--- a/controller/binding.h
+++ b/controller/binding.h
@@ -135,6 +135,7 @@ struct local_binding {
     char *name;
     const struct ovsrec_interface *iface;
     struct ovs_list binding_lports;
+    bool multiple_bindings;
 };
 
 struct local_binding_data {
diff --git a/tests/ovn.at b/tests/ovn.at
index 6552681bd..7a918c639 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -33053,3 +33053,171 @@ check ovn-nbctl --wait=hv sync
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 ])
+
+m4_define([MULTIPLE_OVS_INT],
+  [OVN_FOR_EACH_NORTHD([
+   AT_SETUP([ovn-controller: Multiple OVS interfaces bound to same logical port ($1)])
+   ovn_start
+   net_add n1
+
+   sim_add hv1
+   as hv1
+   ovs-vsctl add-br br-phys
+   ovn_attach n1 br-phys 192.168.0.1
+
+   get_flows()
+   {
+       cookie=${1}
+       ovs-ofctl dump-flows br-int | grep $cookie |
+           sed -e 's/duration=[[0-9.]]*s, //g' |
+           sed -e 's/idle_age=[[0-9]]*, //g' |
+           sed -e 's/n_packets=[[0-9]]*, //g' |
+           sed -e 's/n_bytes=[[0-9]]*, //g'
+   }
+
+   check ovn-nbctl ls-add ls
+   check ovn-nbctl lsp-add ls lp
+   if test X$1 != X; then
+       check ovn-nbctl lsp-set-type lp $1
+   fi
+   check ovn-nbctl lsp-set-addresses lp "00:00:00:01:01:02 192.168.1.2"
+
+   check ovn-nbctl lsp-add ls vm1
+   check ovn-nbctl lsp-set-addresses vm1 "00:00:00:01:01:11 192.168.1.11"
+   check ovs-vsctl add-port br-int vm1 -- set interface vm1 type=internal external_ids:iface-id=vm1
+
+   check ovn-nbctl --wait=hv sync
+
+   check ovs-vsctl add-port br-int lpold -- set interface lpold type=internal
+   check ovs-vsctl set interface lpold external_ids:iface-id=lp
+
+   OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns _uuid find port_binding logical_port=lp) != x])
+   echo ======================================================
+   echo === Flows after iface-id set for the old interface ===
+   echo ======================================================
+   COOKIE=$(ovn-sbctl find port_binding logical_port=lp|grep uuid|cut -d: -f2| cut -c1-8 | sed 's/^\s*0\{0,8\}//')
+
+   OVS_WAIT_UNTIL([
+       ofport=$(ovs-vsctl --bare --columns ofport find Interface name=lpold)
+       ovs-ofctl dump-flows br-int | grep $COOKIE | grep "actions=output:$ofport"
+   ])
+   nb_flows=`ovs-ofctl dump-flows br-int | grep $COOKIE | wc -l`
+   echo $nb_flows "flows after iface-id set for old interface"
+
+   echo ======================================================
+   echo === Flows after iface-id set for the new interface ===
+   echo ======================================================
+   # Set external_ids:iface-id within same transaction as adding the port.
+   # This will generally cause ovn-controller to get initially notified of ovs interface changes with ofport == 0.
+   check ovs-vsctl add-port br-int lpnew -- set interface lpnew type=internal -- set interface lpnew external_ids:iface-id=lp
+   OVS_WAIT_UNTIL([
+       ofport=$(ovs-vsctl --bare --columns ofport find Interface name=lpnew)
+       ovs-ofctl dump-flows br-int | grep $COOKIE | grep "actions=output:$ofport"
+   ])
+   check test "$nb_flows" = $(ovs-ofctl dump-flows br-int | grep $COOKIE | wc -l)
+   flows_lpnew=$(get_flows $COOKIE)
+
+   echo ======================================================
+   echo ======= Flows after old interface is deleted =========
+   echo ======================================================
+   check ovs-vsctl del-port br-int lpold
+   # We do not expect changes, so let's wait for controller to get time to process any update
+   check ovn-nbctl --wait=hv sync
+   check test "$nb_flows" = $(ovs-ofctl dump-flows br-int | grep $COOKIE | wc -l)
+   flows_after_deletion=$(get_flows $COOKIE)
+   check test "$flows_lpnew" = "$flows_after_deletion"
+
+   echo ======================================================
+   echo ======= Flows after lptemp interface is created ====
+   echo ======================================================
+   # Set external_ids:iface-id in a different transaction as adding the port.
+   # This will generally cause ovn-controller to get notified of ovs interface changes with a proper ofport.
+   check ovs-vsctl add-port br-int lptemp -- set Interface lptemp type=internal
+   check ovs-vsctl set Interface lptemp external_ids:iface-id=lp
+   OVS_WAIT_UNTIL([
+       ofport=$(ovs-vsctl --bare --columns ofport find Interface name=lptemp)
+       ovs-ofctl dump-flows br-int | grep $COOKIE | grep "actions=output:$ofport"
+   ])
+   check test "$nb_flows" = $(ovs-ofctl dump-flows br-int | grep $COOKIE | wc -l)
+
+   echo ======================================================
+   echo ======= Flows after lptemp interface is deleted ======
+   echo ======================================================
+   check ovs-vsctl del-port br-int lptemp
+   OVS_WAIT_UNTIL([
+       ofport=$(ovs-vsctl --bare --columns ofport find Interface name=lpnew)
+       echo $ofport
+       ovs-ofctl dump-flows br-int  | grep $COOKIE
+       ovs-ofctl dump-flows br-int | grep $COOKIE | grep "actions=output:$ofport"
+   ])
+   check test "$nb_flows" = $(ovs-ofctl dump-flows br-int | grep $COOKIE | wc -l)
+   flows_after_deletion=$(get_flows $COOKIE)
+   check test "$flows_lpnew" = "$flows_after_deletion"
+
+   echo ======================================================
+   echo ======= Flows after new interface is deleted =========
+   echo ======================================================
+   check ovs-vsctl del-port br-int lpnew
+   OVS_WAIT_UNTIL([
+       nb_flows=`ovs-ofctl dump-flows br-int | grep $COOKIE | wc -l`
+       test "${nb_flows}" = 0
+   ])
+
+   echo ======================================================
+   echo ======= Three interfaces bound to the same port ======
+   echo ======================================================
+   check ovs-vsctl add-port br-int lpold -- set interface lpold type=internal
+   check ovs-vsctl set interface lpold external_ids:iface-id=lp
+   check ovs-vsctl add-port br-int lpnew -- set interface lpnew type=internal
+   check ovs-vsctl set interface lpnew external_ids:iface-id=lp
+
+   # Wait for lpnew  flows to be installed
+   OVS_WAIT_UNTIL([
+       ofport=$(ovs-vsctl --bare --columns ofport find Interface name=lpnew)
+       ovs-ofctl dump-flows br-int | grep $COOKIE | grep "actions=output:$ofport"
+   ])
+   flows_lpnew=$(get_flows $COOKIE)
+   nb_flows=`ovs-ofctl dump-flows br-int | grep $COOKIE | wc -l`
+
+   check ovs-vsctl add-port br-int lptemp -- set Interface lptemp type=internal
+   check ovs-vsctl set Interface lptemp external_ids:iface-id=lp
+
+   # Wait for lptemp  flows to be installed
+   OVS_WAIT_UNTIL([
+       ofport=$(ovs-vsctl --bare --columns ofport find Interface name=lptemp)
+       ovs-ofctl dump-flows br-int | grep $COOKIE | grep "actions=output:$ofport"
+   ])
+
+   # Delete both lpold and lptemp to go to a stable situation
+   check ovs-vsctl del-port br-int lptemp
+   check ovs-vsctl del-port br-int lpold
+
+   OVS_WAIT_UNTIL([
+        test 0 = $(ovs-vsctl show | grep "Port lpold" | wc -l)
+   ])
+
+   # Wait for correct/lpnew flows to be installed
+   OVS_WAIT_UNTIL([
+       ofport=$(ovs-vsctl --bare --columns ofport find Interface name=lpnew)
+       ovs-ofctl dump-flows br-int | grep $COOKIE | grep "actions=output:$ofport"
+   ])
+   check test "$nb_flows" = $(ovs-ofctl dump-flows br-int | grep $COOKIE | wc -l)
+   flows_after_deletion=$(get_flows $COOKIE)
+   check test "$flows_lpnew" = "$flows_after_deletion"
+
+   # Check that recompute still works
+   check ovn-appctl -t ovn-controller recompute
+   OVS_WAIT_UNTIL([
+       ofport=$(ovs-vsctl --bare --columns ofport find Interface name=lpnew)
+       ovs-ofctl dump-flows br-int | grep $COOKIE | grep "actions=output:$ofport"
+   ])
+   check test "$nb_flows" = $(ovs-ofctl dump-flows br-int | grep $COOKIE | wc -l)
+   flows_after_deletion=$(get_flows $COOKIE)
+   check test "$flows_lpnew" = "$flows_after_deletion"
+
+   OVN_CLEANUP([hv1])
+   AT_CLEANUP
+   ])])
+
+MULTIPLE_OVS_INT([localport])
+MULTIPLE_OVS_INT([])
