diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2FlowRuleDriver.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2FlowRuleDriver.java
index c226e60..3c6acf5 100644
--- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2FlowRuleDriver.java
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2FlowRuleDriver.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014-2016 Open Networking Laboratory
+ * Copyright 2016-present Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,221 +16,146 @@
 
 package org.onosproject.drivers.bmv2;
 
-import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import org.onosproject.bmv2.api.runtime.Bmv2ExtensionSelector;
-import org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment;
-import org.onosproject.bmv2.api.runtime.Bmv2TableEntry;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.commons.lang3.tuple.Triple;
+import org.onosproject.bmv2.api.runtime.Bmv2MatchKey;
 import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException;
+import org.onosproject.bmv2.api.runtime.Bmv2TableEntry;
 import org.onosproject.bmv2.ctl.Bmv2ThriftClient;
+import org.onosproject.drivers.bmv2.translators.Bmv2DefaultFlowRuleTranslator;
+import org.onosproject.drivers.bmv2.translators.Bmv2FlowRuleTranslator;
+import org.onosproject.drivers.bmv2.translators.Bmv2FlowRuleTranslatorException;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.driver.AbstractHandlerBehaviour;
 import org.onosproject.net.flow.DefaultFlowEntry;
 import org.onosproject.net.flow.FlowEntry;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.FlowRuleProgrammable;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.ExtensionCriterion;
-import org.onosproject.net.flow.criteria.ExtensionSelector;
-import org.onosproject.net.flow.criteria.ExtensionSelectorType;
-import org.onosproject.net.flow.instructions.ExtensionTreatment;
-import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
-import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.net.flow.instructions.Instructions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
 
 public class Bmv2FlowRuleDriver extends AbstractHandlerBehaviour
         implements FlowRuleProgrammable {
 
-    private final Logger log =
-            LoggerFactory.getLogger(this.getClass());
-
-    // Bmv2 doesn't support proper table dump, use a local store
-    // FIXME: synchronize entries with device
-    private final Map<FlowRule, FlowEntry> deviceEntriesMap = Maps.newHashMap();
-    private final Map<Integer, Set<FlowRule>> tableRulesMap = Maps.newHashMap();
-    private final Map<FlowRule, Long> tableEntryIdsMap = Maps.newHashMap();
+    private static final Logger LOG =
+            LoggerFactory.getLogger(Bmv2FlowRuleDriver.class);
+    // There's no Bmv2 client method to poll flow entries from the device device. gitNeed a local store.
+    private static final ConcurrentMap<Triple<DeviceId, String, Bmv2MatchKey>, Pair<Long, FlowEntry>>
+            ENTRIES_MAP = Maps.newConcurrentMap();
+    private static final Bmv2FlowRuleTranslator TRANSLATOR = new Bmv2DefaultFlowRuleTranslator();
 
     @Override
     public Collection<FlowEntry> getFlowEntries() {
-        return Collections.unmodifiableCollection(
-                deviceEntriesMap.values());
+
+        DeviceId deviceId = handler().data().deviceId();
+
+        List<FlowEntry> entryList = Lists.newArrayList();
+
+        // FIXME: improve this, e.g. might store a separate Map<DeviceId, Collection<FlowEntry>>
+        ENTRIES_MAP.forEach((key, value) -> {
+            if (key.getLeft() == deviceId && value != null) {
+                entryList.add(value.getRight());
+            }
+        });
+
+        return Collections.unmodifiableCollection(entryList);
     }
 
     @Override
     public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
-        Bmv2ThriftClient deviceClient;
-        try {
-            deviceClient = getDeviceClient();
-        } catch (Bmv2RuntimeException e) {
-            return Collections.emptyList();
-        }
 
-        List<FlowRule> appliedFlowRules = Lists.newArrayList();
-
-        for (FlowRule rule : rules) {
-
-            Bmv2TableEntry entry;
-
-            try {
-                entry = parseFlowRule(rule);
-            } catch (IllegalStateException e) {
-                log.error("Unable to parse flow rule", e);
-                continue;
-            }
-
-            // Instantiate flowrule set for table if it does not exist
-            if (!tableRulesMap.containsKey(rule.tableId())) {
-                tableRulesMap.put(rule.tableId(), Sets.newHashSet());
-            }
-
-            if (tableRulesMap.get(rule.tableId()).contains(rule)) {
-                /* Rule is already installed in the table */
-                long entryId = tableEntryIdsMap.get(rule);
-
-                try {
-                    deviceClient.modifyTableEntry(
-                            entry.tableName(), entryId, entry.action());
-
-                    // Replace stored rule as treatment, etc. might have changed
-                    // Java Set doesn't replace on add, remove first
-                    tableRulesMap.get(rule.tableId()).remove(rule);
-                    tableRulesMap.get(rule.tableId()).add(rule);
-                    tableEntryIdsMap.put(rule, entryId);
-                    deviceEntriesMap.put(rule, new DefaultFlowEntry(
-                            rule, FlowEntry.FlowEntryState.ADDED, 0, 0, 0));
-                } catch (Bmv2RuntimeException e) {
-                    log.error("Unable to update flow rule", e);
-                    continue;
-                }
-
-            } else {
-                /* Rule is new */
-                try {
-                    long entryId = deviceClient.addTableEntry(entry);
-
-                    tableRulesMap.get(rule.tableId()).add(rule);
-                    tableEntryIdsMap.put(rule, entryId);
-                    deviceEntriesMap.put(rule, new DefaultFlowEntry(
-                            rule, FlowEntry.FlowEntryState.ADDED, 0, 0, 0));
-                } catch (Bmv2RuntimeException e) {
-                    log.error("Unable to add flow rule", e);
-                    continue;
-                }
-            }
-
-            appliedFlowRules.add(rule);
-        }
-
-        return Collections.unmodifiableCollection(appliedFlowRules);
+        return processFlowRules(rules, Operation.APPLY);
     }
 
     @Override
     public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
+
+        return processFlowRules(rules, Operation.REMOVE);
+    }
+
+    private Collection<FlowRule> processFlowRules(Collection<FlowRule> rules, Operation operation) {
+
+        DeviceId deviceId = handler().data().deviceId();
+
         Bmv2ThriftClient deviceClient;
         try {
-            deviceClient = getDeviceClient();
+            deviceClient = Bmv2ThriftClient.of(deviceId);
         } catch (Bmv2RuntimeException e) {
+            LOG.error("Failed to connect to Bmv2 device", e);
             return Collections.emptyList();
         }
 
-        List<FlowRule> removedFlowRules = Lists.newArrayList();
+        List<FlowRule> processedFlowRules = Lists.newArrayList();
 
         for (FlowRule rule : rules) {
 
-            if (tableEntryIdsMap.containsKey(rule)) {
-                long entryId = tableEntryIdsMap.get(rule);
-                String tableName = parseTableName(rule.tableId());
+            Bmv2TableEntry bmv2Entry;
 
-                try {
-                    deviceClient.deleteTableEntry(tableName, entryId);
-                } catch (Bmv2RuntimeException e) {
-                    log.error("Unable to delete flow rule", e);
-                    continue;
-                }
-
-                /* remove from local store */
-                tableEntryIdsMap.remove(rule);
-                tableRulesMap.get(rule.tableId()).remove(rule);
-                deviceEntriesMap.remove(rule);
-
-                removedFlowRules.add(rule);
+            try {
+                bmv2Entry = TRANSLATOR.translate(rule);
+            } catch (Bmv2FlowRuleTranslatorException e) {
+                LOG.error("Unable to translate flow rule: {}", e.getMessage());
+                continue;
             }
+
+            String tableName = bmv2Entry.tableName();
+            Triple<DeviceId, String, Bmv2MatchKey> entryKey = Triple.of(deviceId, tableName, bmv2Entry.matchKey());
+
+            /*
+            From here on threads are synchronized over entryKey, i.e. serialize operations
+            over the same matchKey of a specific table and device.
+             */
+            ENTRIES_MAP.compute(entryKey, (key, value) -> {
+                try {
+                    if (operation == Operation.APPLY) {
+                        // Apply entry
+                        long entryId;
+                        if (value == null) {
+                            // New entry
+                            entryId = deviceClient.addTableEntry(bmv2Entry);
+                        } else {
+                            // Existing entry
+                            entryId = value.getKey();
+                            // FIXME: check if priority or timeout changed
+                            // In this case we should to re-add the entry (not modify)
+                            deviceClient.modifyTableEntry(tableName, entryId, bmv2Entry.action());
+                        }
+                        // TODO: evaluate flow entry life, bytes and packets
+                        FlowEntry flowEntry = new DefaultFlowEntry(
+                                rule, FlowEntry.FlowEntryState.ADDED, 0, 0, 0);
+                        value = Pair.of(entryId, flowEntry);
+                    } else {
+                        // Remove entry
+                        if (value == null) {
+                            // Entry not found in map, how come?
+                            LOG.debug("Trying to remove entry, but entry ID not found: " + entryKey);
+                        } else {
+                            deviceClient.deleteTableEntry(tableName, value.getKey());
+                            value = null;
+                        }
+                    }
+                    // If here, no exceptions... things went well :)
+                    processedFlowRules.add(rule);
+                } catch (Bmv2RuntimeException e) {
+                    LOG.error("Unable to " + operation.name().toLowerCase() + " flow rule", e);
+                } catch (Exception e) {
+                    LOG.error("Uncaught exception while processing flow rule", e);
+                }
+                return value;
+            });
         }
 
-        return Collections.unmodifiableCollection(removedFlowRules);
+        return processedFlowRules;
     }
 
-    private Bmv2TableEntry parseFlowRule(FlowRule flowRule) {
-
-        // TODO make it pipeline dependant, i.e. implement mapping
-
-        Bmv2TableEntry.Builder entryBuilder = Bmv2TableEntry.builder();
-
-        // Check selector
-        ExtensionCriterion ec =
-                (ExtensionCriterion) flowRule
-                        .selector().getCriterion(Criterion.Type.EXTENSION);
-        Preconditions.checkState(
-                flowRule.selector().criteria().size() == 1
-                        && ec != null,
-                "Selector must have only 1 criterion of type EXTENSION");
-        ExtensionSelector es = ec.extensionSelector();
-        Preconditions.checkState(
-                es.type() == ExtensionSelectorType.ExtensionSelectorTypes.P4_BMV2_MATCH_KEY.type(),
-                "ExtensionSelectorType must be P4_BMV2_MATCH_KEY");
-
-        // Selector OK, get Bmv2MatchKey
-        entryBuilder.withMatchKey(((Bmv2ExtensionSelector) es).matchKey());
-
-        // Check treatment
-        Instruction inst = flowRule.treatment().allInstructions().get(0);
-        Preconditions.checkState(
-                flowRule.treatment().allInstructions().size() == 1
-                        && inst.type() == Instruction.Type.EXTENSION,
-                "Treatment must have only 1 instruction of type EXTENSION");
-        ExtensionTreatment et =
-                ((Instructions.ExtensionInstructionWrapper) inst)
-                        .extensionInstruction();
-
-        Preconditions.checkState(
-                et.type() == ExtensionTreatmentType.ExtensionTreatmentTypes.P4_BMV2_ACTION.type(),
-                "ExtensionTreatmentType must be P4_BMV2_ACTION");
-
-        // Treatment OK, get Bmv2Action
-        entryBuilder.withAction(((Bmv2ExtensionTreatment) et).getAction());
-
-        // Table name
-        entryBuilder.withTableName(parseTableName(flowRule.tableId()));
-
-        if (!flowRule.isPermanent()) {
-            entryBuilder.withTimeout(flowRule.timeout());
-        }
-
-        entryBuilder.withPriority(flowRule.priority());
-
-        return entryBuilder.build();
+    private enum Operation {
+        APPLY, REMOVE
     }
-
-    private String parseTableName(int tableId) {
-        // TODO: map tableId with tableName according to P4 JSON
-        return "table" + String.valueOf(tableId);
-    }
-
-    private Bmv2ThriftClient getDeviceClient() throws Bmv2RuntimeException {
-        try {
-            return Bmv2ThriftClient.of(handler().data().deviceId());
-        } catch (Bmv2RuntimeException e) {
-            log.error("Failed to connect to Bmv2 device", e);
-            throw e;
-        }
-    }
-}
+}
\ No newline at end of file
