diff --git a/controller/lflow.c b/controller/lflow.c
index d0b335893..66c31db9e 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -90,7 +90,8 @@ static void lflows_processed_add(struct hmap *lflows_processed,
 static void lflows_processed_remove(struct hmap *lflows_processed,
                                     struct lflow_processed_node *node);
 static void lflow_resource_add(struct lflow_resource_ref *, enum ref_type,
-                               const char *ref_name, const struct uuid *);
+                               const char *ref_name, const struct uuid *,
+                               size_t ref_count);
 static struct ref_lflow_node *ref_lflow_lookup(struct hmap *ref_lflow_table,
                                                enum ref_type,
                                                const char *ref_name);
@@ -115,7 +116,7 @@ lookup_port_cb(const void *aux_, const char *port_name, unsigned int *portp)
      * in the future when the lport's port binding changes, the logical flow
      * that references this lport can be reprocessed. */
     lflow_resource_add(aux->lfrr, REF_TYPE_PORTBINDING, port_name,
-                       &aux->lflow->header_.uuid);
+                       &aux->lflow->header_.uuid, 0);
 
     const struct sbrec_port_binding *pb
         = lport_lookup_by_name(aux->sbrec_port_binding_by_name, port_name);
@@ -131,7 +132,7 @@ lookup_port_cb(const void *aux_, const char *port_name, unsigned int *portp)
     struct ds mg_key = DS_EMPTY_INITIALIZER;
     get_mc_group_key(port_name, aux->dp->tunnel_key, &mg_key);
     lflow_resource_add(aux->lfrr, REF_TYPE_MC_GROUP, ds_cstr(&mg_key),
-                       &aux->lflow->header_.uuid);
+                       &aux->lflow->header_.uuid, 0);
     ds_destroy(&mg_key);
 
     const struct sbrec_multicast_group *mg = mcgroup_lookup_by_dp_name(
@@ -173,7 +174,7 @@ is_chassis_resident_cb(const void *c_aux_, const char *port_name)
      * that in the future when the lport's port-binding changes the logical
      * flow that references this lport can be reprocessed. */
     lflow_resource_add(c_aux->lfrr, REF_TYPE_PORTBINDING, port_name,
-                       &c_aux->lflow->header_.uuid);
+                       &c_aux->lflow->header_.uuid, 0);
 
     const struct sbrec_port_binding *pb
         = lport_lookup_by_name(c_aux->sbrec_port_binding_by_name, port_name);
@@ -266,7 +267,8 @@ lflow_ref_lookup(struct hmap *lflow_ref_table,
 
 static void
 lflow_resource_add(struct lflow_resource_ref *lfrr, enum ref_type type,
-                   const char *ref_name, const struct uuid *lflow_uuid)
+                   const char *ref_name, const struct uuid *lflow_uuid,
+                   size_t ref_count)
 {
     struct ref_lflow_node *rlfn = ref_lflow_lookup(&lfrr->ref_lflow_table,
                                                    type, ref_name);
@@ -302,6 +304,7 @@ lflow_resource_add(struct lflow_resource_ref *lfrr, enum ref_type type,
 
     struct lflow_ref_list_node *lrln = xzalloc(sizeof *lrln);
     lrln->lflow_uuid = *lflow_uuid;
+    lrln->ref_count = ref_count;
     lrln->rlfn = rlfn;
     hmap_insert(&rlfn->lflow_uuids, &lrln->hmap_node, uuid_hash(lflow_uuid));
     ovs_list_push_back(&lfrn->lflow_ref_head, &lrln->list_node);
@@ -750,7 +753,7 @@ convert_match_to_expr(const struct sbrec_logical_flow *lflow,
                       struct lflow_resource_ref *lfrr,
                       bool *pg_addr_set_ref)
 {
-    struct sset addr_sets_ref = SSET_INITIALIZER(&addr_sets_ref);
+    struct shash addr_sets_ref = SHASH_INITIALIZER(&addr_sets_ref);
     struct sset port_groups_ref = SSET_INITIALIZER(&port_groups_ref);
     char *error = NULL;
 
@@ -758,22 +761,23 @@ convert_match_to_expr(const struct sbrec_logical_flow *lflow,
                                        port_groups, &addr_sets_ref,
                                        &port_groups_ref, dp->tunnel_key,
                                        &error);
-    const char *addr_set_name;
-    SSET_FOR_EACH (addr_set_name, &addr_sets_ref) {
-        lflow_resource_add(lfrr, REF_TYPE_ADDRSET, addr_set_name,
-                           &lflow->header_.uuid);
+    struct shash_node *addr_sets_ref_node;
+    SHASH_FOR_EACH (addr_sets_ref_node, &addr_sets_ref) {
+        lflow_resource_add(lfrr, REF_TYPE_ADDRSET, addr_sets_ref_node->name,
+                           &lflow->header_.uuid,
+                           *(size_t *)addr_sets_ref_node->data);
     }
     const char *port_group_name;
     SSET_FOR_EACH (port_group_name, &port_groups_ref) {
         lflow_resource_add(lfrr, REF_TYPE_PORTGROUP, port_group_name,
-                           &lflow->header_.uuid);
+                           &lflow->header_.uuid, 0);
     }
 
     if (pg_addr_set_ref) {
         *pg_addr_set_ref = (!sset_is_empty(&port_groups_ref) ||
-                            !sset_is_empty(&addr_sets_ref));
+                            !shash_is_empty(&addr_sets_ref));
     }
-    sset_destroy(&addr_sets_ref);
+    shash_destroy(&addr_sets_ref);
     sset_destroy(&port_groups_ref);
 
     if (!error) {
@@ -812,7 +816,7 @@ consider_logical_flow__(const struct sbrec_logical_flow *lflow,
     const char *io_port = smap_get(&lflow->tags, "in_out_port");
     if (io_port) {
         lflow_resource_add(l_ctx_out->lfrr, REF_TYPE_PORTBINDING, io_port,
-                           &lflow->header_.uuid);
+                           &lflow->header_.uuid, 0);
         const struct sbrec_port_binding *pb
             = lport_lookup_by_name(l_ctx_in->sbrec_port_binding_by_name,
                                    io_port);
diff --git a/controller/lflow.h b/controller/lflow.h
index d6dad17ec..b131b6cb6 100644
--- a/controller/lflow.h
+++ b/controller/lflow.h
@@ -105,6 +105,9 @@ struct lflow_ref_list_node {
     struct ovs_list list_node; /* node in lflow_ref_node.lflow_ref_head. */
     struct hmap_node hmap_node; /* node in ref_lflow_node.lflow_uuids. */
     struct uuid lflow_uuid;
+    size_t ref_count; /* Reference count of the resource by this lflow.
+                         Currently used for the resource type REF_TYPE_ADDRSET
+                         only, and for other types it is always 0. */
     struct ref_lflow_node *rlfn;
 };
 
diff --git a/include/ovn/expr.h b/include/ovn/expr.h
index 5b232c246..cb3baf001 100644
--- a/include/ovn/expr.h
+++ b/include/ovn/expr.h
@@ -419,13 +419,13 @@ size_t expr_size(const struct expr *);
 struct expr *expr_parse(struct lexer *, const struct shash *symtab,
                         const struct shash *addr_sets,
                         const struct shash *port_groups,
-                        struct sset *addr_sets_ref,
+                        struct shash *addr_sets_ref,
                         struct sset *port_groups_ref,
                         int64_t dp_id);
 struct expr *expr_parse_string(const char *, const struct shash *symtab,
                                const struct shash *addr_sets,
                                const struct shash *port_groups,
-                               struct sset *addr_sets_ref,
+                               struct shash *addr_sets_ref,
                                struct sset *port_groups_ref,
                                int64_t dp_id,
                                char **errorp);
diff --git a/lib/expr.c b/lib/expr.c
index 2fdb7e3bb..2c178d87f 100644
--- a/lib/expr.c
+++ b/lib/expr.c
@@ -519,7 +519,7 @@ struct expr_context {
     const struct shash *symtab;    /* Symbol table. */
     const struct shash *addr_sets; /* Address set table. */
     const struct shash *port_groups; /* Port group table. */
-    struct sset *addr_sets_ref;      /* The set of address set referenced. */
+    struct shash *addr_sets_ref;      /* The set of address set referenced. */
     struct sset *port_groups_ref;    /* The set of port groups referenced. */
     int64_t dp_id;                   /* The tunnel_key of the datapath for
                                         which we're parsing the current
@@ -798,7 +798,15 @@ parse_addr_sets(struct expr_context *ctx, struct expr_constant_set *cs,
                 size_t *allocated_values)
 {
     if (ctx->addr_sets_ref) {
-        sset_add(ctx->addr_sets_ref, ctx->lexer->token.s);
+        size_t *ref_count = shash_find_data(ctx->addr_sets_ref,
+                                            ctx->lexer->token.s);
+        if (!ref_count) {
+            ref_count = xmalloc(sizeof *ref_count);
+            *ref_count = 1;
+            shash_add(ctx->addr_sets_ref, ctx->lexer->token.s, ref_count);
+        } else {
+            (*ref_count)++;
+        }
     }
 
     struct expr_constant_set *addr_sets
@@ -1513,7 +1521,7 @@ struct expr *
 expr_parse(struct lexer *lexer, const struct shash *symtab,
            const struct shash *addr_sets,
            const struct shash *port_groups,
-           struct sset *addr_sets_ref,
+           struct shash *addr_sets_ref,
            struct sset *port_groups_ref,
            int64_t dp_id)
 {
@@ -1537,7 +1545,7 @@ struct expr *
 expr_parse_string(const char *s, const struct shash *symtab,
                   const struct shash *addr_sets,
                   const struct shash *port_groups,
-                  struct sset *addr_sets_ref,
+                  struct shash *addr_sets_ref,
                   struct sset *port_groups_ref,
                   int64_t dp_id,
                   char **errorp)
