diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java
index 8217255..d96de2f 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java
@@ -16,34 +16,57 @@
 
 package org.onosproject.net.intent.impl.installer;
 
+import com.google.common.collect.Lists;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetworkResource;
+import org.onosproject.net.flow.DefaultFlowRule;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.FlowRuleOperations;
 import org.onosproject.net.flow.FlowRuleOperationsContext;
 import org.onosproject.net.flow.FlowRuleService;
 import org.onosproject.net.intent.FlowRuleIntent;
-import org.onosproject.net.intent.IntentInstallCoordinator;
+import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentData;
 import org.onosproject.net.intent.IntentExtensionService;
-import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentInstallCoordinator;
 import org.onosproject.net.intent.IntentInstaller;
-import org.onosproject.net.intent.impl.IntentManager;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentStore;
 import org.onosproject.net.intent.ObjectiveTrackerService;
+import org.onosproject.net.intent.impl.IntentManager;
+import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.net.intent.IntentInstaller.Direction.ADD;
 import static org.onosproject.net.intent.IntentInstaller.Direction.REMOVE;
+import static org.onosproject.net.intent.IntentState.INSTALLED;
+import static org.onosproject.net.intent.IntentState.REALLOCATING;
+import static org.onosproject.net.intent.constraint.NonDisruptiveConstraint.requireNonDisruptive;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -63,23 +86,71 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected FlowRuleService flowRuleService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentStore store;
+
+    private ScheduledExecutorService nonDisruptiveIntentInstaller;
+
+    private static final int DEFAULT_NON_DISRUPTIVE_INSTALLATION_WAITING_TIME = 1;
+    @Property(name = "nonDisruptiveInstallationWaitingTime",
+            intValue = DEFAULT_NON_DISRUPTIVE_INSTALLATION_WAITING_TIME,
+            label = "Number of seconds to wait during the non-disruptive installation phases")
+    private int nonDisruptiveInstallationWaitingTime = DEFAULT_NON_DISRUPTIVE_INSTALLATION_WAITING_TIME;
+
+    protected final Logger log = getLogger(IntentManager.class);
+
+    private boolean isReallocationStageFailed = false;
+
+    private static final LinkComparator LINK_COMPARATOR = new LinkComparator();
+
     @Activate
     public void activate() {
         intentExtensionService.registerInstaller(FlowRuleIntent.class, this);
+        nonDisruptiveIntentInstaller =
+                newSingleThreadScheduledExecutor(groupedThreads("onos/intent", "non-disruptive-installer", log));
+        configService.registerProperties(getClass());
     }
 
     @Deactivate
     public void deactivated() {
         intentExtensionService.unregisterInstaller(FlowRuleIntent.class);
+        configService.unregisterProperties(getClass(), false);
     }
 
-    protected final Logger log = getLogger(IntentManager.class);
+    @Modified
+    public void modified(ComponentContext context) {
+
+        if (context == null) {
+            nonDisruptiveInstallationWaitingTime = DEFAULT_NON_DISRUPTIVE_INSTALLATION_WAITING_TIME;
+            log.info("Restored default installation time for non-disruptive reallocation (1 sec.)");
+            return;
+        }
+
+        String s = Tools.get(context.getProperties(), "nonDisruptiveInstallationWaitingTime");
+        int nonDisruptiveTime = isNullOrEmpty(s) ? nonDisruptiveInstallationWaitingTime : Integer.parseInt(s);
+        if (nonDisruptiveTime != nonDisruptiveInstallationWaitingTime) {
+            nonDisruptiveInstallationWaitingTime = nonDisruptiveTime;
+            log.info("Reconfigured non-disruptive reallocation with installation delay {} sec.",
+                     nonDisruptiveInstallationWaitingTime);
+        }
+    }
 
     @Override
     public void apply(IntentOperationContext<FlowRuleIntent> context) {
         Optional<IntentData> toUninstall = context.toUninstall();
         Optional<IntentData> toInstall = context.toInstall();
 
+        if (toInstall.isPresent() && toUninstall.isPresent()) {
+            Intent intentToInstall = toInstall.get().intent();
+            if (requireNonDisruptive(intentToInstall) && INSTALLED.equals(toUninstall.get().state())) {
+                reallocate(context);
+                return;
+            }
+        }
+
         if (!toInstall.isPresent() && !toUninstall.isPresent()) {
             // Nothing to do.
             intentInstallCoordinator.intentInstallSuccess(context);
@@ -176,6 +247,307 @@
         flowRuleService.apply(operations);
     }
 
+    private void reallocate(IntentOperationContext<FlowRuleIntent> context) {
+
+        Optional<IntentData> toUninstall = context.toUninstall();
+        Optional<IntentData> toInstall = context.toInstall();
+
+        //TODO: Update the Intent store with this information
+        toInstall.get().setState(REALLOCATING);
+
+        store.write(toInstall.get());
+
+        List<FlowRuleIntent> uninstallIntents = Lists.newArrayList(context.intentsToUninstall());
+        List<FlowRuleIntent> installIntents = Lists.newArrayList(context.intentsToInstall());
+        FlowRuleOperations.Builder firstStageOperationsBuilder = FlowRuleOperations.builder();
+        List<FlowRule> secondStageFlowRules = Lists.newArrayList();
+        FlowRuleOperations.Builder thirdStageOperationsBuilder = FlowRuleOperations.builder();
+        FlowRuleOperations.Builder finalStageOperationsBuilder = FlowRuleOperations.builder();
+
+        prepareReallocation(uninstallIntents, installIntents,
+                            firstStageOperationsBuilder, secondStageFlowRules,
+                            thirdStageOperationsBuilder, finalStageOperationsBuilder);
+
+        trackIntentResources(toUninstall.get(), uninstallIntents, REMOVE);
+        trackIntentResources(toInstall.get(), installIntents, ADD);
+
+        CountDownLatch stageCompleteLatch = new CountDownLatch(1);
+
+        FlowRuleOperations firstStageOperations = firstStageOperationsBuilder
+                .build(new StageOperation(context, stageCompleteLatch));
+
+        flowRuleService.apply(firstStageOperations);
+
+        try {
+            stageCompleteLatch.await(nonDisruptiveInstallationWaitingTime, TimeUnit.SECONDS);
+            if (isReallocationStageFailed) {
+                log.error("Reallocation FAILED in stage one: the following FlowRuleOperations are not executed {}",
+                          firstStageOperations);
+                return;
+            } else {
+                log.debug("Reallocation stage one completed");
+            }
+        } catch (Exception e) {
+            log.warn("Latch exception in the reallocation stage one");
+        }
+
+        for (FlowRule flowRule : secondStageFlowRules) {
+            stageCompleteLatch = new CountDownLatch(1);
+            FlowRuleOperations operations = FlowRuleOperations.builder()
+                    .newStage()
+                    .remove(flowRule)
+                    .build(new StageOperation(context, stageCompleteLatch));
+            nonDisruptiveIntentInstaller.schedule(new NonDisruptiveInstallation(operations),
+                                                  nonDisruptiveInstallationWaitingTime,
+                                                  TimeUnit.SECONDS);
+            try {
+                stageCompleteLatch.await(nonDisruptiveInstallationWaitingTime, TimeUnit.SECONDS);
+                if (isReallocationStageFailed) {
+                    log.error("Reallocation FAILED in stage two: " +
+                                      "the following FlowRuleOperations are not executed {}",
+                              operations);
+                    return;
+                } else {
+                    log.debug("Reallocation stage two completed");
+                }
+            } catch (Exception e) {
+                log.warn("Latch exception in the reallocation stage two");
+            }
+        }
+
+        stageCompleteLatch = new CountDownLatch(1);
+        FlowRuleOperations thirdStageOperations = thirdStageOperationsBuilder
+                .build(new StageOperation(context, stageCompleteLatch));
+
+        nonDisruptiveIntentInstaller.schedule(new NonDisruptiveInstallation(thirdStageOperations),
+                                              nonDisruptiveInstallationWaitingTime,
+                                              TimeUnit.SECONDS);
+        try {
+            stageCompleteLatch.await(nonDisruptiveInstallationWaitingTime, TimeUnit.SECONDS);
+            if (isReallocationStageFailed) {
+                log.error("Reallocation FAILED in stage three: " +
+                                  "the following FlowRuleOperations are not executed {}",
+                          thirdStageOperations);
+                return;
+            } else {
+                log.debug("Reallocation stage three completed");
+            }
+        } catch (Exception e) {
+            log.warn("Latch exception in the reallocation stage three");
+        }
+
+        FlowRuleOperationsContext flowRuleOperationsContext = new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                intentInstallCoordinator.intentInstallSuccess(context);
+                log.info("Non-disruptive reallocation completed for intent {}", toInstall.get().key());
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                intentInstallCoordinator.intentInstallFailed(context);
+            }
+        };
+
+        FlowRuleOperations finalStageOperations = finalStageOperationsBuilder.build(flowRuleOperationsContext);
+        flowRuleService.apply(finalStageOperations);
+    }
+
+    /**
+     * This method prepares the {@link FlowRule} required for every reallocation stage.
+     *     <p>Stage 1: the FlowRules of the new path are installed,
+     *     with a lower priority only on the devices shared with the old path;</p>
+     *     <p>Stage 2: the FlowRules of the old path are removed from the ingress to the egress points,
+     *     only in the shared devices;</p>
+     *     <p>Stage 3: the FlowRules with a lower priority are restored to the original one;</p>
+     *     <p>Stage 4: the remaining FlowRules of the old path are deleted.</p>
+     *
+     * @param uninstallIntents the previous FlowRuleIntent
+     * @param installIntents the new FlowRuleIntent to be installed
+     * @param firstStageBuilder the first stage operation builder
+     * @param secondStageFlowRules the second stage FlowRules
+     * @param thirdStageBuilder the third stage operation builder
+     * @param finalStageBuilder the last stage operation builder
+     */
+    private void prepareReallocation(List<FlowRuleIntent> uninstallIntents, List<FlowRuleIntent> installIntents,
+                                     FlowRuleOperations.Builder firstStageBuilder,
+                                     List<FlowRule> secondStageFlowRules,
+                                     FlowRuleOperations.Builder thirdStageBuilder,
+                                     FlowRuleOperations.Builder finalStageBuilder) {
+
+
+        // Filter out same intents and intents with same flow rules
+        installIntents.forEach(installIntent -> {
+            uninstallIntents.forEach(uninstallIntent -> {
+
+                List<FlowRule> uninstallFlowRules = Lists.newArrayList(uninstallIntent.flowRules());
+                List<FlowRule> installFlowRules = Lists.newArrayList(installIntent.flowRules());
+
+                List<FlowRule> secondStageRules = Lists.newArrayList();
+                List<FlowRule> thirdStageRules = Lists.newArrayList();
+
+                List<DeviceId> orderedDeviceList = createIngressToEgressDeviceList(installIntent.resources());
+
+                uninstallIntent.flowRules().forEach(flowRuleToUnistall -> {
+                    installIntent.flowRules().forEach(flowRuleToInstall -> {
+
+                        if (flowRuleToInstall.exactMatch(flowRuleToUnistall)) {
+                            //The FlowRules are in common (i.e., we are sharing the path)
+                            uninstallFlowRules.remove(flowRuleToInstall);
+                            installFlowRules.remove(flowRuleToInstall);
+                        } else if (flowRuleToInstall.deviceId().equals(flowRuleToUnistall.deviceId())) {
+                            //FlowRules that have a device in common but
+                            // different treatment/selector (i.e., overlapping path)
+                            FlowRule flowRuleWithLowerPriority = DefaultFlowRule.builder()
+                                    .withPriority(flowRuleToInstall.priority() - 1)
+                                    .withSelector(flowRuleToInstall.selector())
+                                    .forDevice(flowRuleToInstall.deviceId())
+                                    .makePermanent()
+                                    .withTreatment(flowRuleToInstall.treatment())
+                                    .fromApp(new DefaultApplicationId(flowRuleToInstall.appId(),
+                                                                      "org.onosproject.net.intent"))
+                                    .build();
+
+                            //Update the FlowRule to be installed with one with a lower priority
+                            installFlowRules.remove(flowRuleToInstall);
+                            installFlowRules.add(flowRuleWithLowerPriority);
+
+                            //Add the FlowRule to be uninstalled to the second stage of non-disruptive update
+                            secondStageRules.add(flowRuleToUnistall);
+                            uninstallFlowRules.remove(flowRuleToUnistall);
+
+                            thirdStageRules.add(flowRuleToInstall);
+                            uninstallFlowRules.add(flowRuleWithLowerPriority);
+                        }
+                    });
+                });
+
+                firstStageBuilder.newStage();
+                installFlowRules.forEach(firstStageBuilder::add);
+
+                Collections.sort(secondStageRules, new SecondStageComparator(orderedDeviceList));
+                secondStageFlowRules.addAll(secondStageRules);
+
+                thirdStageBuilder.newStage();
+                thirdStageRules.forEach(thirdStageBuilder::add);
+
+                finalStageBuilder.newStage();
+                uninstallFlowRules.forEach(finalStageBuilder::remove);
+            });
+        });
+
+    }
+
+    private class StageOperation implements FlowRuleOperationsContext {
+
+        private IntentOperationContext<FlowRuleIntent> context;
+        private CountDownLatch stageCompleteLatch;
+
+        public StageOperation(IntentOperationContext<FlowRuleIntent> context, CountDownLatch stageCompleteLatch) {
+            this.context = context;
+            this.stageCompleteLatch = stageCompleteLatch;
+            isReallocationStageFailed = false;
+        }
+
+        @Override
+        public void onSuccess(FlowRuleOperations ops) {
+            stageCompleteLatch.countDown();
+            log.debug("FlowRuleOperations correctly completed");
+        }
+
+        @Override
+        public void onError(FlowRuleOperations ops) {
+            intentInstallCoordinator.intentInstallFailed(context);
+            isReallocationStageFailed = true;
+            stageCompleteLatch.countDown();
+            log.debug("Installation error for {}", ops);
+        }
+    }
+
+    private final class SecondStageComparator implements Comparator<FlowRule> {
+
+        private List<DeviceId> deviceIds;
+
+        private SecondStageComparator(List<DeviceId> deviceIds) {
+            this.deviceIds = deviceIds;
+        }
+
+        @Override
+        public int compare(FlowRule o1, FlowRule o2) {
+            Integer index1 = deviceIds.indexOf(o1.deviceId());
+            Integer index2 = deviceIds.indexOf(o2.deviceId());
+            return index1.compareTo(index2);
+        }
+    }
+
+    /**
+     * Create a list of devices ordered from the ingress to the egress of a path.
+     * @param resources the resources of the intent
+     * @return a list of devices
+     */
+    private List<DeviceId> createIngressToEgressDeviceList(Collection<NetworkResource> resources) {
+        List<DeviceId> deviceIds = Lists.newArrayList();
+        List<Link> links = Lists.newArrayList();
+
+        for (NetworkResource resource : resources) {
+            if (resource instanceof Link) {
+                Link linkToAdd = (Link) resource;
+                if (linkToAdd.type() != Link.Type.EDGE) {
+                    links.add(linkToAdd);
+                }
+            }
+        }
+
+        Collections.sort(links, LINK_COMPARATOR);
+
+        int i = 0;
+        for (Link orderedLink : links) {
+            deviceIds.add(orderedLink.src().deviceId());
+            if (i == resources.size() - 1) {
+                deviceIds.add(orderedLink.dst().deviceId());
+            }
+            i++;
+        }
+
+        return deviceIds;
+    }
+
+    /**
+     * Compares two links in order to find which one is before or after the other.
+     */
+    private static class LinkComparator implements Comparator<Link> {
+
+        @Override
+        public int compare(Link l1, Link l2) {
+
+            //l1 is before l2
+            if (l1.dst().deviceId() == l2.src().deviceId()) {
+                return -1;
+            }
+
+            //l1 is after l2
+            if (l1.src().deviceId() == l2.dst().deviceId()) {
+                return 1;
+            }
+
+            //l2 and l1 are not connected to a common device
+            return 0;
+        }
+    }
+
+    private final class NonDisruptiveInstallation implements Runnable {
+
+        private FlowRuleOperations op;
+
+        private NonDisruptiveInstallation(FlowRuleOperations op) {
+            this.op = op;
+        }
+        @Override
+        public void run() {
+            flowRuleService.apply(this.op);
+        }
+    }
+
     /**
      * Track or un-track network resource of a Intent and it's installable
      * Intents.
