diff --git a/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
index f18143f..2eb52f3 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
@@ -29,6 +29,8 @@
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
+import org.onlab.util.PredictableExecutor;
+import org.onlab.util.PredictableExecutor.PickyCallable;
 import org.onosproject.cluster.NodeId;
 import org.onosproject.mastership.MastershipEvent;
 import org.onosproject.net.ConnectPoint;
@@ -55,6 +57,10 @@
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Lock;
@@ -92,6 +98,9 @@
         = newScheduledThreadPool(1, groupedThreads("masterChg", "mstch-%d", log));
     private ScheduledExecutorService executorServiceFRR
         = newScheduledThreadPool(1, groupedThreads("fullRR", "fullRR-%d", log));
+    // Route populators - 0 will leverage available processors
+    private static final int DEFAULT_THREADS = 0;
+    private ExecutorService routePopulators;
 
     private Instant lastRoutingChange = Instant.EPOCH;
     private Instant lastFullReroute = Instant.EPOCH;
@@ -112,14 +121,10 @@
     public enum Status {
         // population process is not started yet.
         IDLE,
-
         // population process started.
         STARTED,
-
-        // population process was aborted due to errors, mostly for groups not
-        // found.
+        // population process was aborted due to errors, mostly for groups not found.
         ABORTED,
-
         // population process was finished successfully.
         SUCCEEDED
     }
@@ -137,6 +142,8 @@
                 .build().asJavaMap();
         this.shouldProgramCache = Maps.newConcurrentMap();
         update(srManager);
+        this.routePopulators = new PredictableExecutor(DEFAULT_THREADS,
+                                                      groupedThreads("onos/sr", "r-populator-%d", log));
     }
 
     /**
@@ -205,6 +212,7 @@
         executorService.shutdown();
         executorServiceMstChg.shutdown();
         executorServiceFRR.shutdown();
+        routePopulators.shutdown();
     }
 
     //////////////////////////////////////
@@ -648,9 +656,8 @@
      *                     the path.
      * @return true if successful
      */
-    private boolean redoRoutingEdgePairs(Set<EdgePair> edgePairs,
-                                      Set<IpPrefix> subnets,
-                                      Set<ArrayList<DeviceId>> changedRoutes) {
+    private boolean redoRoutingEdgePairs(Set<EdgePair> edgePairs, Set<IpPrefix> subnets,
+                                         Set<ArrayList<DeviceId>> changedRoutes) {
         for (EdgePair ep : edgePairs) {
             // temp store for a target's changedRoutes to this edge-pair
             Map<DeviceId, Set<ArrayList<DeviceId>>> targetRoutes = new HashMap<>();
@@ -683,102 +690,135 @@
             }
             // so now for this edgepair we have a per target set of routechanges
             // process target->edgePair route
+            List<Future<Boolean>> futures = Lists.newArrayList();
             for (Map.Entry<DeviceId, Set<ArrayList<DeviceId>>> entry :
                             targetRoutes.entrySet()) {
                 log.debug("* redoRoutingDstPair Target:{} -> edge-pair {}",
                           entry.getKey(), ep);
-                DeviceId targetSw = entry.getKey();
-                Map<DeviceId, Set<DeviceId>> perDstNextHops = new HashMap<>();
-                entry.getValue().forEach(route -> {
-                    Set<DeviceId> nhops = getNextHops(route.get(0), route.get(1));
-                    log.debug("route: target {} -> dst {} found with next-hops {}",
-                              route.get(0), route.get(1), nhops);
-                    perDstNextHops.put(route.get(1), nhops);
-                });
-
-                List<Set<IpPrefix>> batchedSubnetDev1, batchedSubnetDev2;
-                if (subnets != null) {
-                    batchedSubnetDev1 = Lists.<Set<IpPrefix>>newArrayList(Sets.newHashSet(subnets));
-                    batchedSubnetDev2 = Lists.<Set<IpPrefix>>newArrayList(Sets.newHashSet(subnets));
-                } else {
-                    batchedSubnetDev1 = config.getBatchedSubnets(ep.dev1);
-                    batchedSubnetDev2 = config.getBatchedSubnets(ep.dev2);
-                }
-                List<Set<IpPrefix>> batchedSubnetBoth = Streams
-                        .zip(batchedSubnetDev1.stream(), batchedSubnetDev2.stream(), (a, b) -> Sets.intersection(a, b))
-                        .filter(set -> !set.isEmpty())
-                        .collect(Collectors.toList());
-                List<Set<IpPrefix>> batchedSubnetDev1Only = Streams
-                        .zip(batchedSubnetDev1.stream(), batchedSubnetDev2.stream(), (a, b) -> Sets.difference(a, b))
-                        .filter(set -> !set.isEmpty())
-                        .collect(Collectors.toList());
-                List<Set<IpPrefix>> batchedSubnetDev2Only = Streams
-                        .zip(batchedSubnetDev1.stream(), batchedSubnetDev2.stream(), (a, b) -> Sets.difference(b, a))
-                        .filter(set -> !set.isEmpty())
-                        .collect(Collectors.toList());
-
-                Set<DeviceId> nhDev1 = perDstNextHops.get(ep.dev1);
-                Set<DeviceId> nhDev2 = perDstNextHops.get(ep.dev2);
-
-                // handle routing to subnets common to edge-pair
-                // only if the targetSw is not part of the edge-pair and there
-                // exists a next hop to at least one of the devices in the edge-pair
-                if (!ep.includes(targetSw)
-                        && ((nhDev1 != null && !nhDev1.isEmpty()) || (nhDev2 != null && !nhDev2.isEmpty()))) {
-                    log.trace("getSubnets on both {} and {}: {}", ep.dev1, ep.dev2, batchedSubnetBoth);
-                    for (Set<IpPrefix> prefixes : batchedSubnetBoth) {
-                        if (!populateEcmpRoutingRulePartial(
-                                targetSw,
-                                ep.dev1, ep.dev2,
-                                perDstNextHops,
-                                prefixes)) {
-                            return false; // abort everything and fail fast
-                        }
-                    }
-
-                }
-                // handle routing to subnets that only belong to dev1 only if
-                // a next-hop exists from the target to dev1
-                if (!batchedSubnetDev1Only.isEmpty() &&
-                        batchedSubnetDev1Only.stream().anyMatch(subnet -> !subnet.isEmpty()) &&
-                        nhDev1 != null  && !nhDev1.isEmpty()) {
-                    Map<DeviceId, Set<DeviceId>> onlyDev1NextHops = new HashMap<>();
-                    onlyDev1NextHops.put(ep.dev1, nhDev1);
-                    log.trace("getSubnets on {} only: {}", ep.dev1, batchedSubnetDev1Only);
-                    for (Set<IpPrefix> prefixes : batchedSubnetDev1Only) {
-                        if (!populateEcmpRoutingRulePartial(
-                                targetSw,
-                                ep.dev1, null,
-                                onlyDev1NextHops,
-                                prefixes)) {
-                            return false; // abort everything and fail fast
-                        }
-                    }
-                }
-                // handle routing to subnets that only belong to dev2 only if
-                // a next-hop exists from the target to dev2
-                if (!batchedSubnetDev2Only.isEmpty() &&
-                        batchedSubnetDev2Only.stream().anyMatch(subnet -> !subnet.isEmpty()) &&
-                        nhDev2 != null && !nhDev2.isEmpty()) {
-                    Map<DeviceId, Set<DeviceId>> onlyDev2NextHops = new HashMap<>();
-                    onlyDev2NextHops.put(ep.dev2, nhDev2);
-                    log.trace("getSubnets on {} only: {}", ep.dev2, batchedSubnetDev2Only);
-                    for (Set<IpPrefix> prefixes : batchedSubnetDev2Only) {
-                        if (!populateEcmpRoutingRulePartial(
-                                targetSw,
-                                ep.dev2, null,
-                                onlyDev2NextHops,
-                                prefixes)) {
-                            return false; // abort everything and fail fast
-                        }
-                    }
-                }
+                futures.add(routePopulators.submit(new RedoRoutingEdgePair(entry.getKey(), entry.getValue(),
+                                                                           subnets, ep)));
+            }
+            if (!checkJobs(futures)) {
+                return false;
             }
             // if it gets here it has succeeded for all targets to this edge-pair
         }
         return true;
     }
 
+    private final class RedoRoutingEdgePair implements PickyCallable<Boolean> {
+        private DeviceId targetSw;
+        private Set<ArrayList<DeviceId>> routes;
+        private Set<IpPrefix> subnets;
+        private EdgePair ep;
+
+        /**
+         * Builds a RedoRoutingEdgePair task which provides a result.
+         *
+         * @param targetSw the target switch
+         * @param routes the changed routes
+         * @param subnets the subnets
+         * @param ep the edge pair
+         */
+        RedoRoutingEdgePair(DeviceId targetSw, Set<ArrayList<DeviceId>> routes,
+                            Set<IpPrefix> subnets, EdgePair ep) {
+            this.targetSw = targetSw;
+            this.routes = routes;
+            this.subnets = subnets;
+            this.ep = ep;
+        }
+
+        @Override
+        public Boolean call() throws Exception {
+            return redoRoutingEdgePair();
+        }
+
+        @Override
+        public int hint() {
+            return targetSw.hashCode();
+        }
+
+        private boolean redoRoutingEdgePair() {
+            Map<DeviceId, Set<DeviceId>> perDstNextHops = new HashMap<>();
+            routes.forEach(route -> {
+                Set<DeviceId> nhops = getNextHops(route.get(0), route.get(1));
+                log.debug("route: target {} -> dst {} found with next-hops {}",
+                          route.get(0), route.get(1), nhops);
+                perDstNextHops.put(route.get(1), nhops);
+            });
+
+            List<Set<IpPrefix>> batchedSubnetDev1, batchedSubnetDev2;
+            if (subnets != null) {
+                batchedSubnetDev1 = Lists.<Set<IpPrefix>>newArrayList(Sets.newHashSet(subnets));
+                batchedSubnetDev2 = Lists.<Set<IpPrefix>>newArrayList(Sets.newHashSet(subnets));
+            } else {
+                batchedSubnetDev1 = config.getBatchedSubnets(ep.dev1);
+                batchedSubnetDev2 = config.getBatchedSubnets(ep.dev2);
+            }
+            List<Set<IpPrefix>> batchedSubnetBoth = Streams
+                    .zip(batchedSubnetDev1.stream(), batchedSubnetDev2.stream(), (a, b) -> Sets.intersection(a, b))
+                    .filter(set -> !set.isEmpty())
+                    .collect(Collectors.toList());
+            List<Set<IpPrefix>> batchedSubnetDev1Only = Streams
+                    .zip(batchedSubnetDev1.stream(), batchedSubnetDev2.stream(), (a, b) -> Sets.difference(a, b))
+                    .filter(set -> !set.isEmpty())
+                    .collect(Collectors.toList());
+            List<Set<IpPrefix>> batchedSubnetDev2Only = Streams
+                    .zip(batchedSubnetDev1.stream(), batchedSubnetDev2.stream(), (a, b) -> Sets.difference(b, a))
+                    .filter(set -> !set.isEmpty())
+                    .collect(Collectors.toList());
+
+            Set<DeviceId> nhDev1 = perDstNextHops.get(ep.dev1);
+            Set<DeviceId> nhDev2 = perDstNextHops.get(ep.dev2);
+
+            // handle routing to subnets common to edge-pair
+            // only if the targetSw is not part of the edge-pair and there
+            // exists a next hop to at least one of the devices in the edge-pair
+            if (!ep.includes(targetSw)
+                    && ((nhDev1 != null && !nhDev1.isEmpty()) || (nhDev2 != null && !nhDev2.isEmpty()))) {
+                log.trace("getSubnets on both {} and {}: {}", ep.dev1, ep.dev2, batchedSubnetBoth);
+                for (Set<IpPrefix> prefixes : batchedSubnetBoth) {
+                    if (!populateEcmpRoutingRulePartial(targetSw, ep.dev1, ep.dev2,
+                                                        perDstNextHops, prefixes)) {
+                        return false; // abort everything and fail fast
+                    }
+                }
+
+            }
+            // handle routing to subnets that only belong to dev1 only if
+            // a next-hop exists from the target to dev1
+            if (!batchedSubnetDev1Only.isEmpty() &&
+                    batchedSubnetDev1Only.stream().anyMatch(subnet -> !subnet.isEmpty()) &&
+                    nhDev1 != null  && !nhDev1.isEmpty()) {
+                Map<DeviceId, Set<DeviceId>> onlyDev1NextHops = new HashMap<>();
+                onlyDev1NextHops.put(ep.dev1, nhDev1);
+                log.trace("getSubnets on {} only: {}", ep.dev1, batchedSubnetDev1Only);
+                for (Set<IpPrefix> prefixes : batchedSubnetDev1Only) {
+                    if (!populateEcmpRoutingRulePartial(targetSw, ep.dev1, null,
+                                                        onlyDev1NextHops, prefixes)) {
+                        return false; // abort everything and fail fast
+                    }
+                }
+            }
+            // handle routing to subnets that only belong to dev2 only if
+            // a next-hop exists from the target to dev2
+            if (!batchedSubnetDev2Only.isEmpty() &&
+                    batchedSubnetDev2Only.stream().anyMatch(subnet -> !subnet.isEmpty()) &&
+                    nhDev2 != null && !nhDev2.isEmpty()) {
+                Map<DeviceId, Set<DeviceId>> onlyDev2NextHops = new HashMap<>();
+                onlyDev2NextHops.put(ep.dev2, nhDev2);
+                log.trace("getSubnets on {} only: {}", ep.dev2, batchedSubnetDev2Only);
+                for (Set<IpPrefix> prefixes : batchedSubnetDev2Only) {
+                    if (!populateEcmpRoutingRulePartial(targetSw, ep.dev2, null,
+                                                        onlyDev2NextHops, prefixes)) {
+                        return false; // abort everything and fail fast
+                    }
+                }
+            }
+            return true;
+        }
+    }
+
     /**
      * Programs targetSw in the changedRoutes for given prefixes reachable by
      * a destination switch that is not part of an edge-pair.
@@ -794,8 +834,7 @@
      *                     the path.
      * @return true if successful
      */
-    private boolean redoRoutingIndividualDests(Set<IpPrefix> subnets,
-                                               Set<ArrayList<DeviceId>> changedRoutes,
+    private boolean redoRoutingIndividualDests(Set<IpPrefix> subnets, Set<ArrayList<DeviceId>> changedRoutes,
                                                Set<DeviceId> updatedDevices) {
         // aggregate route-path changes for each dst device
         HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> routesBydevice =
@@ -810,28 +849,19 @@
             }
             deviceRoutes.add(route);
         }
+        // iterate over the impacted devices
         for (DeviceId impactedDstDevice : routesBydevice.keySet()) {
             ArrayList<ArrayList<DeviceId>> deviceRoutes =
                     routesBydevice.get(impactedDstDevice);
+            List<Future<Boolean>> futures = Lists.newArrayList();
             for (ArrayList<DeviceId> route: deviceRoutes) {
                 log.debug("* redoRoutingIndiDst Target: {} -> dst: {}",
                           route.get(0), route.get(1));
-                DeviceId targetSw = route.get(0);
-                DeviceId dstSw = route.get(1); // same as impactedDstDevice
-                Set<DeviceId> nextHops = getNextHops(targetSw, dstSw);
-                if (nextHops.isEmpty()) {
-                    log.debug("Could not find next hop from target:{} --> dst {} "
-                            + "skipping this route", targetSw, dstSw);
-                    continue;
-                }
-                Map<DeviceId, Set<DeviceId>> nhops = new HashMap<>();
-                nhops.put(dstSw, nextHops);
-                if (!populateEcmpRoutingRulePartial(targetSw, dstSw, null, nhops,
-                         (subnets == null) ? Sets.newHashSet() : subnets)) {
-                    return false; // abort routing and fail fast
-                }
-                log.debug("Populating flow rules from target: {} to dst: {}"
-                        + " is successful", targetSw, dstSw);
+                futures.add(routePopulators.submit(new RedoRoutingIndividualDest(subnets, route)));
+            }
+            // check the execution of each job
+            if (!checkJobs(futures)) {
+                return false;
             }
             //Only if all the flows for all impacted routes to a
             //specific target are pushed successfully, update the
@@ -848,6 +878,49 @@
         return true;
     }
 
+    private final class RedoRoutingIndividualDest implements PickyCallable<Boolean> {
+        private DeviceId targetSw;
+        private ArrayList<DeviceId> route;
+        private Set<IpPrefix> subnets;
+
+        /**
+         * Builds a RedoRoutingIndividualDest task, which provides a result.
+         *
+         * @param subnets a set of prefixes
+         * @param route a route-path change
+         */
+        RedoRoutingIndividualDest(Set<IpPrefix> subnets, ArrayList<DeviceId> route) {
+            this.targetSw = route.get(0);
+            this.route = route;
+            this.subnets = subnets;
+        }
+
+        @Override
+        public Boolean call() throws Exception {
+            DeviceId dstSw = route.get(1); // same as impactedDstDevice
+            Set<DeviceId> nextHops = getNextHops(targetSw, dstSw);
+            if (nextHops.isEmpty()) {
+                log.debug("Could not find next hop from target:{} --> dst {} "
+                                  + "skipping this route", targetSw, dstSw);
+                return true;
+            }
+            Map<DeviceId, Set<DeviceId>> nhops = new HashMap<>();
+            nhops.put(dstSw, nextHops);
+            if (!populateEcmpRoutingRulePartial(targetSw, dstSw, null, nhops,
+                                                (subnets == null) ? Sets.newHashSet() : subnets)) {
+                return false; // abort routing and fail fast
+            }
+            log.debug("Populating flow rules from target: {} to dst: {}"
+                              + " is successful", targetSw, dstSw);
+            return true;
+        }
+
+        @Override
+        public int hint() {
+            return targetSw.hashCode();
+        }
+    }
+
     /**
      * Populate ECMP rules for subnets from target to destination via nexthops.
      *
@@ -859,11 +932,8 @@
      * @param subnets Subnets to be populated. If empty, populate all configured subnets.
      * @return true if it succeeds in populating rules
      */ // refactor
-    private boolean populateEcmpRoutingRulePartial(DeviceId targetSw,
-                                                   DeviceId destSw1,
-                                                   DeviceId destSw2,
-                                                   Map<DeviceId, Set<DeviceId>> nextHops,
-                                                   Set<IpPrefix> subnets) {
+    private boolean populateEcmpRoutingRulePartial(DeviceId targetSw, DeviceId destSw1, DeviceId destSw2,
+                                                   Map<DeviceId, Set<DeviceId>> nextHops, Set<IpPrefix> subnets) {
         boolean result;
         // If both target switch and dest switch are edge routers, then set IP
         // rule for both subnet and router IP.
@@ -922,9 +992,7 @@
             // individual destinations, even if the dsts are part of edge-pairs.
             log.debug(". populateEcmpRoutingRulePartial in device{} towards {} for "
                     + "all MPLS rules", targetSw, destSw1);
-            result = rulePopulator.populateMplsRule(targetSw, destSw1,
-                                                    nextHops.get(destSw1),
-                                                    dest1RouterIpv4);
+            result = rulePopulator.populateMplsRule(targetSw, destSw1, nextHops.get(destSw1), dest1RouterIpv4);
             if (!result) {
                 return false;
             }
@@ -937,8 +1005,7 @@
                     log.warn(e.getMessage());
                 }
                 if (v4sid != v6sid) {
-                    result = rulePopulator.populateMplsRule(targetSw, destSw1,
-                                                            nextHops.get(destSw1),
+                    result = rulePopulator.populateMplsRule(targetSw, destSw1, nextHops.get(destSw1),
                                                             dest1RouterIpv6);
                     if (!result) {
                         return false;
@@ -953,9 +1020,7 @@
             log.debug(". populateEcmpRoutingRulePartial in device{} towards {} for "
                               + "all MPLS rules", targetSw, destSw1);
 
-            result = rulePopulator.populateMplsRule(targetSw, destSw1,
-                                                        nextHops.get(destSw1),
-                                                        dest1RouterIpv4);
+            result = rulePopulator.populateMplsRule(targetSw, destSw1, nextHops.get(destSw1), dest1RouterIpv4);
             if (!result) {
                 return false;
             }
@@ -969,8 +1034,7 @@
                     log.warn(e.getMessage());
                 }
                 if (v4sid != v6sid) {
-                    result = rulePopulator.populateMplsRule(targetSw, destSw1,
-                                                            nextHops.get(destSw1),
+                    result = rulePopulator.populateMplsRule(targetSw, destSw1, nextHops.get(destSw1),
                                                             dest1RouterIpv6);
                     if (!result) {
                         return false;
@@ -1140,14 +1204,43 @@
      * @return true if succeed
      */
     protected boolean revokeSubnet(Set<IpPrefix> subnets) {
-        statusLock.lock();
-        try {
-            return Sets.newHashSet(srManager.deviceService.getAvailableDevices()).stream()
-                    .map(Device::id)
-                    .filter(this::shouldProgram)
-                    .allMatch(targetSw -> srManager.routingRulePopulator.revokeIpRuleForSubnet(targetSw, subnets));
-        } finally {
-            statusLock.unlock();
+        DeviceId targetSw;
+        List<Future<Boolean>> futures = Lists.newArrayList();
+        for (Device sw : srManager.deviceService.getAvailableDevices()) {
+            targetSw = sw.id();
+            if (shouldProgram(targetSw)) {
+                futures.add(routePopulators.submit(new RevokeSubnet(targetSw, subnets)));
+            } else {
+                futures.add(CompletableFuture.completedFuture(true));
+            }
+        }
+        // check the execution of each job
+        return checkJobs(futures);
+    }
+
+    private final class RevokeSubnet implements PickyCallable<Boolean> {
+        private DeviceId targetSw;
+        private Set<IpPrefix> subnets;
+
+        /**
+         * Builds a RevokeSubnet task, which provides a result.
+         *
+         * @param subnets a set of prefixes
+         * @param targetSw target switch
+         */
+        RevokeSubnet(DeviceId targetSw, Set<IpPrefix> subnets) {
+            this.targetSw = targetSw;
+            this.subnets = subnets;
+        }
+
+        @Override
+        public Boolean call() throws Exception {
+            return srManager.routingRulePopulator.revokeIpRuleForSubnet(targetSw, subnets);
+        }
+
+        @Override
+        public int hint() {
+            return targetSw.hashCode();
         }
     }
 
@@ -1930,4 +2023,24 @@
             prevRun = (thisRun == null) ? prevRun : thisRun;
         }
     }
+
+    // Check jobs completion. It returns false if one of the job fails
+    // and cancel the remaining
+    private boolean checkJobs(List<Future<Boolean>> futures) {
+        boolean completed = true;
+        for (Future<Boolean> future : futures) {
+            try {
+                if (completed) {
+                    if (!future.get()) {
+                        completed = false;
+                    }
+                } else {
+                    future.cancel(true);
+                }
+            } catch (InterruptedException | ExecutionException e) {
+                completed = false;
+            }
+        }
+        return completed;
+    }
 }
diff --git a/app/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/app/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
index 7dddd3f..f19b68c 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -505,10 +505,11 @@
         // Route simplification will be off in case of the nexthop location at target switch is down
         // (routing through spine case)
         boolean routeSimplOff = pairDev.isPresent() && pairDev.get().equals(destSw1) && destSw2 == null;
-        // Iterates over the routes
+        // Iterates over the routes. Checking:
         // If route simplification is enabled
         // If the target device is another leaf in the network
         if (srManager.routeSimplification && !routeSimplOff) {
+            Set<IpPrefix> subnetsToBePopulated = Sets.newHashSet();
             for (IpPrefix subnet : subnets) {
                 // Skip route programming on the target device
                 // If route simplification applies
@@ -519,19 +520,12 @@
                     continue;
                 }
                 // populate the route in the remaning scenarios
-                if (!populateIpRuleForRouter(targetSw, subnet, destSw1, destSw2, nextHops)) {
-                    return false;
-                }
+                subnetsToBePopulated.add(subnet);
             }
-        } else {
-            // Populate IP flow rules for all the subnets.
-            for (IpPrefix subnet : subnets) {
-                if (!populateIpRuleForRouter(targetSw, subnet, destSw1, destSw2, nextHops)) {
-                    return false;
-                }
-            }
+            subnets = subnetsToBePopulated;
         }
-        return true;
+        // populate the remaining routes in the target switch
+        return populateIpRulesForRouter(targetSw, subnets, destSw1, destSw2, nextHops);
     }
 
     /**
@@ -551,11 +545,11 @@
     }
 
     /**
-     * Populates IP flow rules for an IP prefix in the target device. The prefix
-     * is reachable via destination device(s).
+     * Populates IP flow rules for a set of IP prefix in the target device.
+     * The prefix are reachable via destination device(s).
      *
      * @param targetSw target device ID to set the rules
-     * @param ipPrefix the IP prefix
+     * @param subnets the set of IP prefix
      * @param destSw1 destination switch where the prefixes are reachable
      * @param destSw2 paired destination switch if one exists for the subnets/prefixes.
      *                Should be null if there is no paired destination switch (by config)
@@ -566,98 +560,112 @@
      *                  should not be an entry for destSw2 in this map.
      * @return true if all rules are set successfully, false otherwise
      */
-    private boolean populateIpRuleForRouter(DeviceId targetSw,
-                                           IpPrefix ipPrefix, DeviceId destSw1,
-                                           DeviceId destSw2,
-                                           Map<DeviceId, Set<DeviceId>> nextHops) {
-        int segmentId1, segmentId2 = -1;
+    private boolean populateIpRulesForRouter(DeviceId targetSw,
+                                             Set<IpPrefix> subnets,
+                                             DeviceId destSw1, DeviceId destSw2,
+                                             Map<DeviceId, Set<DeviceId>> nextHops) {
+        // pre-compute the needed information
+        int segmentIdIPv41, segmentIdIPv42 = -1;
+        int segmentIdIPv61, segmentIdIPv62 = -1;
+        TrafficTreatment treatment = null;
+        DestinationSet dsIPv4, dsIPv6;
+        TrafficSelector metaIpv4Selector, metaIpv6Selector = null;
+        int nextIdIPv4, nextIdIPv6, nextId;
+        TrafficSelector selector;
+        // start with MPLS SIDs
         try {
-            if (ipPrefix.isIp4()) {
-                segmentId1 = config.getIPv4SegmentId(destSw1);
-                if (destSw2 != null) {
-                    segmentId2 = config.getIPv4SegmentId(destSw2);
-                }
-            } else {
-                segmentId1 = config.getIPv6SegmentId(destSw1);
-                if (destSw2 != null) {
-                    segmentId2 = config.getIPv6SegmentId(destSw2);
-                }
+            segmentIdIPv41 = config.getIPv4SegmentId(destSw1);
+            segmentIdIPv61 = config.getIPv6SegmentId(destSw1);
+            if (destSw2 != null) {
+                segmentIdIPv42 = config.getIPv4SegmentId(destSw2);
+                segmentIdIPv62 = config.getIPv6SegmentId(destSw2);
             }
         } catch (DeviceConfigNotFoundException e) {
             log.warn(e.getMessage() + " Aborting populateIpRuleForRouter.");
             return false;
         }
-
-        TrafficSelector.Builder sbuilder = buildIpSelectorFromIpPrefix(ipPrefix);
-        TrafficSelector selector = sbuilder.build();
-
-        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
-        DestinationSet ds;
-        TrafficTreatment treatment;
-        DestinationSet.DestinationSetType dsType;
-
+        // build the IPv4 and IPv6 destination set
         if (destSw2 == null) {
             // single dst - create destination set based on next-hop
             // If the next hop is the same as the final destination, then MPLS
             // label is not set.
             Set<DeviceId> nhd1 = nextHops.get(destSw1);
             if (nhd1.size() == 1 && nhd1.iterator().next().equals(destSw1)) {
-                tbuilder.immediate().decNwTtl();
-                ds = DestinationSet.createTypePushNone(destSw1);
-                treatment = tbuilder.build();
+                dsIPv4 = DestinationSet.createTypePushNone(destSw1);
+                dsIPv6 = DestinationSet.createTypePushNone(destSw1);
+                treatment = DefaultTrafficTreatment.builder()
+                        .immediate()
+                        .decNwTtl()
+                        .build();
             } else {
-                ds = DestinationSet.createTypePushBos(segmentId1, destSw1);
-                treatment = null;
+                dsIPv4 = DestinationSet.createTypePushBos(segmentIdIPv41, destSw1);
+                dsIPv6 = DestinationSet.createTypePushBos(segmentIdIPv61, destSw1);
             }
         } else {
             // dst pair - IP rules for dst-pairs are always from other edge nodes
             // the destination set needs to have both destinations, even if there
             // are no next hops to one of them
-            ds = DestinationSet.createTypePushBos(segmentId1, destSw1, segmentId2, destSw2);
-            treatment = null;
+            dsIPv4 = DestinationSet.createTypePushBos(segmentIdIPv41, destSw1, segmentIdIPv42, destSw2);
+            dsIPv6 = DestinationSet.createTypePushBos(segmentIdIPv61, destSw1, segmentIdIPv62, destSw2);
         }
 
         // setup metadata to pass to nextObjective - indicate the vlan on egress
         // if needed by the switch pipeline. Since neighbor sets are always to
         // other neighboring routers, there is no subnet assigned on those ports.
-        TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder(selector);
-        metabuilder.matchVlanId(srManager.getDefaultInternalVlan());
+        metaIpv4Selector = buildIpv4Selector()
+                .matchVlanId(srManager.getDefaultInternalVlan())
+                .build();
+        metaIpv6Selector = buildIpv6Selector()
+                .matchVlanId(srManager.getDefaultInternalVlan())
+                .build();
+        // get the group handler of the target switch
         DefaultGroupHandler grpHandler = srManager.getGroupHandler(targetSw);
         if (grpHandler == null) {
             log.warn("populateIPRuleForRouter: groupHandler for device {} "
-                    + "not found", targetSw);
+                             + "not found", targetSw);
             return false;
         }
-
-        int nextId = grpHandler.getNextObjectiveId(ds, nextHops,
-                                                   metabuilder.build(), false);
-        if (nextId <= 0) {
-            log.warn("No next objective in {} for ds: {}", targetSw, ds);
+        // get next id
+        nextIdIPv4 = grpHandler.getNextObjectiveId(dsIPv4, nextHops, metaIpv4Selector, false);
+        if (nextIdIPv4 <= 0) {
+            log.warn("No next objective in {} for ds: {}", targetSw, dsIPv4);
             return false;
         }
-
-        ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
-                .builder()
-                .fromApp(srManager.appId)
-                .makePermanent()
-                .nextStep(nextId)
-                .withSelector(selector)
-                .withPriority(getPriorityFromPrefix(ipPrefix))
-                .withFlag(ForwardingObjective.Flag.SPECIFIC);
-        if (treatment != null) {
-            fwdBuilder.withTreatment(treatment);
+        nextIdIPv6 = grpHandler.getNextObjectiveId(dsIPv6, nextHops, metaIpv6Selector, false);
+        if (nextIdIPv6 <= 0) {
+            log.warn("No next objective in {} for ds: {}", targetSw, dsIPv6);
+            return false;
         }
-        log.debug("Installing IPv4 forwarding objective for router IP/subnet {} "
-                + "in switch {} with nextId: {}", ipPrefix, targetSw, nextId);
-        ObjectiveContext context = new DefaultObjectiveContext(
-                (objective) -> log.debug("IP rule for router {} populated in dev:{}",
-                                         ipPrefix, targetSw),
-                (objective, error) ->
-                        log.warn("Failed to populate IP rule for router {}: {} in dev:{}",
-                                 ipPrefix, error, targetSw));
-        srManager.flowObjectiveService.forward(targetSw, fwdBuilder.add(context));
-        rulePopulationCounter.incrementAndGet();
-
+        // build all the flow rules and send to the device
+        for (IpPrefix subnet : subnets) {
+            selector = buildIpSelectorFromIpPrefix(subnet).build();
+            if (subnet.isIp4()) {
+                nextId = nextIdIPv4;
+            } else {
+                nextId = nextIdIPv6;
+            }
+            ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
+                    .builder()
+                    .fromApp(srManager.appId)
+                    .makePermanent()
+                    .nextStep(nextId)
+                    .withSelector(selector)
+                    .withPriority(getPriorityFromPrefix(subnet))
+                    .withFlag(ForwardingObjective.Flag.SPECIFIC);
+            if (treatment != null) {
+                fwdBuilder.withTreatment(treatment);
+            }
+            log.debug("Installing {} forwarding objective for router IP/subnet {} "
+                              + "in switch {} with nextId: {}", subnet.isIp4() ? "IPv4" : "IPv6",
+                      subnet, targetSw, nextId);
+            ObjectiveContext context = new DefaultObjectiveContext(
+                    (objective) -> log.debug("IP rule for router {} populated in dev:{}",
+                                             subnet, targetSw),
+                    (objective, error) -> log.warn("Failed to populate IP rule for router {}: {} in dev:{}",
+                                                   subnet, error, targetSw));
+            srManager.flowObjectiveService.forward(targetSw, fwdBuilder.add(context));
+        }
+        rulePopulationCounter.addAndGet(subnets.size());
         return true;
     }
 
@@ -1299,20 +1307,26 @@
         }
     }
 
-    /**
-     * Method to build IPv4 or IPv6 selector.
-     *
-     * @param addressToMatch the address to match
-     */
+    // Method for building an IPv4 selector
+    private TrafficSelector.Builder buildIpv4Selector() {
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4);
+        return selectorBuilder;
+    }
+
+    // Method for building an IPv6 selector
+    private TrafficSelector.Builder buildIpv6Selector() {
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+        selectorBuilder.matchEthType(Ethernet.TYPE_IPV6);
+        return selectorBuilder;
+    }
+
+    // Method for building an IPv4 or IPv6 selector from an IP address
     private TrafficSelector.Builder buildIpSelectorFromIpAddress(IpAddress addressToMatch) {
         return buildIpSelectorFromIpPrefix(addressToMatch.toIpPrefix());
     }
 
-    /**
-     * Method to build IPv4 or IPv6 selector.
-     *
-     * @param prefixToMatch the prefix to match
-     */
+    // Method for building an IPv4 or IPv6 selector from an IP prefix
     private TrafficSelector.Builder buildIpSelectorFromIpPrefix(IpPrefix prefixToMatch) {
         TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
         // If the prefix is IPv4
