diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
index fc7e568..07759e3 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
@@ -28,8 +28,11 @@
 import org.onosproject.core.CoreService;
 import org.onosproject.core.IdGenerator;
 import org.onosproject.event.AbstractListenerManager;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.flow.FlowRuleService;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupService;
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentBatchDelegate;
 import org.onosproject.net.intent.IntentCompiler;
@@ -42,6 +45,8 @@
 import org.onosproject.net.intent.IntentStore;
 import org.onosproject.net.intent.IntentStoreDelegate;
 import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.intent.impl.compiler.PointToPointIntentCompiler;
 import org.onosproject.net.intent.impl.phase.FinalIntentProcessPhase;
 import org.onosproject.net.intent.impl.phase.IntentProcessPhase;
 import org.osgi.service.component.ComponentContext;
@@ -123,6 +128,9 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ComponentConfigService configService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected GroupService groupService;
+
     private ExecutorService batchExecutor;
     private ExecutorService workerExecutor;
 
@@ -234,6 +242,15 @@
         checkNotNull(intent, INTENT_NULL);
         IntentData data = new IntentData(intent, IntentState.PURGE_REQ, null);
         store.addPending(data);
+
+        // remove associated group if there is one
+        if (intent instanceof PointToPointIntent) {
+            PointToPointIntent pointIntent = (PointToPointIntent) intent;
+            DeviceId deviceId = pointIntent.ingressPoint().deviceId();
+            GroupKey groupKey = PointToPointIntentCompiler.makeGroupKey(intent.id());
+            groupService.removeGroup(deviceId, groupKey,
+                                     intent.appId());
+        }
     }
 
     @Override
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java
index 4b51714..6dd4ebd 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java
@@ -20,6 +20,7 @@
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.ElementId;
 import org.onosproject.net.Path;
 import org.onosproject.net.intent.ConnectivityIntent;
@@ -108,6 +109,29 @@
     }
 
     /**
+     * Computes a disjoint path between two ConnectPoints.
+     *
+     * @param intent intent on which behalf path is being computed
+     * @param one    start of the path
+     * @param two    end of the path
+     * @return DisjointPath         between the two
+     * @throws PathNotFoundException if two paths cannot be found
+     */
+    protected DisjointPath getDisjointPath(ConnectivityIntent intent,
+                           ElementId one, ElementId two) {
+        Set<DisjointPath> paths = pathService.getDisjointPaths(one, two, weight(intent.constraints()));
+        final List<Constraint> constraints = intent.constraints();
+        ImmutableList<DisjointPath> filtered = FluentIterable.from(paths)
+                .filter(path -> checkPath(path, constraints))
+                .toList();
+        if (filtered.isEmpty()) {
+            throw new PathNotFoundException(one, two);
+        }
+        // TODO: let's be more intelligent about this eventually
+        return filtered.iterator().next();
+    }
+
+    /**
      * Edge-weight capable of evaluating link cost using a set of constraints.
      */
     protected class ConstraintBasedLinkWeight implements LinkWeight {
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentCompiler.java
index ff69f29..fdcdd00 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathIntentCompiler.java
@@ -82,7 +82,7 @@
         compile(this, intent, rules, devices);
 
 
-        return ImmutableList.of(new FlowRuleIntent(appId, null, rules, intent.resources()));
+        return ImmutableList.of(new FlowRuleIntent(appId, null, rules, intent.resources(), intent.type()));
     }
 
     @Override
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java
index 28d7ea5..0de641a 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java
@@ -18,17 +18,51 @@
 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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultPath;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.EdgeLink;
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.intent.FlowRuleIntent;
 import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentId;
 import org.onosproject.net.intent.PathIntent;
 import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.intent.constraint.ProtectionConstraint;
+import org.onosproject.net.intent.impl.PathNotFoundException;
+import org.onosproject.net.link.LinkService;
 import org.onosproject.net.provider.ProviderId;
 
+import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
 
 import static java.util.Arrays.asList;
 import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
@@ -45,6 +79,18 @@
             new ProviderId("core", "org.onosproject.core", true);
     // TODO: consider whether the default cost is appropriate or not
     public static final int DEFAULT_COST = 1;
+    protected static final int PRIORITY = Intent.DEFAULT_INTENT_PRIORITY;
+    protected boolean erasePrimary = false;
+    protected boolean eraseBackup = false;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected GroupService groupService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
 
     @Activate
     public void activate() {
@@ -63,20 +109,160 @@
         ConnectPoint egressPoint = intent.egressPoint();
 
         if (ingressPoint.deviceId().equals(egressPoint.deviceId())) {
-            List<Link> links = asList(createEdgeLink(ingressPoint, true), createEdgeLink(egressPoint, false));
-            return asList(createPathIntent(new DefaultPath(PID, links, DEFAULT_COST), intent));
+            return createZeroHopIntent(ingressPoint, egressPoint, intent);
         }
 
+        // proceed with no protected paths
+        if (!ProtectionConstraint.requireProtectedPath(intent)) {
+            return createUnprotectedIntent(ingressPoint, egressPoint, intent);
+        }
+
+        try {
+            // attempt to compute and implement backup path
+            return createProtectedIntent(ingressPoint, egressPoint, intent, installable);
+        } catch (PathNotFoundException e) {
+            // no disjoint path extant -- maximum one path exists between devices
+            return createSinglePathIntent(ingressPoint, egressPoint, intent, installable);
+        }
+    }
+
+    private List<Intent> createZeroHopIntent(ConnectPoint ingressPoint,
+                                             ConnectPoint egressPoint,
+                                             PointToPointIntent intent) {
+        List<Link> links = asList(createEdgeLink(ingressPoint, true), createEdgeLink(egressPoint, false));
+        return asList(createPathIntent(new DefaultPath(PID, links, DEFAULT_COST),
+                                       intent, PathIntent.ProtectionType.PRIMARY));
+    }
+
+    private List<Intent> createUnprotectedIntent(ConnectPoint ingressPoint,
+                                                 ConnectPoint egressPoint,
+                                                 PointToPointIntent intent) {
         List<Link> links = new ArrayList<>();
         Path path = getPath(intent, ingressPoint.deviceId(),
-                egressPoint.deviceId());
+                            egressPoint.deviceId());
 
         links.add(createEdgeLink(ingressPoint, true));
         links.addAll(path.links());
         links.add(createEdgeLink(egressPoint, false));
 
         return asList(createPathIntent(new DefaultPath(PID, links, path.cost(),
-                                                       path.annotations()), intent));
+                                                       path.annotations()), intent,
+                                       PathIntent.ProtectionType.PRIMARY));
+    }
+
+    //FIXME: Compatibility with EncapsulationConstraint
+    private List<Intent> createProtectedIntent(ConnectPoint ingressPoint,
+                                               ConnectPoint egressPoint,
+                                               PointToPointIntent intent,
+                                               List<Intent> installable) {
+        DisjointPath path = getDisjointPath(intent, ingressPoint.deviceId(),
+                                            egressPoint.deviceId());
+
+        List<Intent> reusableIntents = null;
+        if (installable != null) {
+            reusableIntents = filterInvalidSubIntents(installable, intent);
+            if (reusableIntents.size() == installable.size()) {
+                // all old paths are still viable
+                return installable;
+            }
+        }
+
+        List<Intent> intentList = new ArrayList<>();
+
+        // primary path intent
+        List<Link> links = new ArrayList<>();
+        links.addAll(path.links());
+        links.add(createEdgeLink(egressPoint, false));
+
+        // backup path intent
+        List<Link> backupLinks = new ArrayList<>();
+        backupLinks.addAll(path.backup().links());
+        backupLinks.add(createEdgeLink(egressPoint, false));
+
+        /*
+         * One of the old paths is still entirely intact. This old path has
+         * already been made primary, so we must add a backup path intent
+         * and modify the failover group treatment accordingly.
+         */
+        if (reusableIntents != null && reusableIntents.size() > 1) {
+            /*
+             * Ensures that the egress port on source device is different than
+             * that of existing path so that failover group will be useful
+             * (would not be useful if both output ports in group bucket were
+             * the same). Does not necessarily ensure that the new backup path
+             * is entirely disjoint from the old path.
+             */
+            PortNumber primaryPort = getPrimaryPort(intent);
+            if (primaryPort != null && !links.get(0).src().port().equals(primaryPort)) {
+                reusableIntents.add(createPathIntent(new DefaultPath(PID, links,
+                                                                     path.cost(), path.annotations()),
+                                                     intent, PathIntent.ProtectionType.BACKUP));
+                updateFailoverGroup(intent, links);
+                return reusableIntents;
+
+            } else {
+                reusableIntents.add(createPathIntent(new DefaultPath(PID, backupLinks, path.backup().cost(),
+                                     path.backup().annotations()), intent, PathIntent.ProtectionType.BACKUP));
+                updateFailoverGroup(intent, backupLinks);
+                return reusableIntents;
+            }
+        }
+
+        intentList.add(createPathIntent(new DefaultPath(PID, links, path.cost(), path.annotations()),
+                                        intent, PathIntent.ProtectionType.PRIMARY));
+        intentList.add(createPathIntent(new DefaultPath(PID, backupLinks, path.backup().cost(),
+                                        path.backup().annotations()), intent, PathIntent.ProtectionType.BACKUP));
+
+        // Create fast failover flow rule intent or, if it already exists,
+        // add contents appropriately.
+        if (groupService.getGroup(ingressPoint.deviceId(),
+                                  makeGroupKey(intent.id())) == null) {
+            // manufactured fast failover flow rule intent
+            createFailoverTreatmentGroup(path.links(), path.backup().links(), intent);
+
+            FlowRuleIntent frIntent = new FlowRuleIntent(intent.appId(),
+                                                         createFailoverFlowRules(intent),
+                                                         asList(ingressPoint.deviceId()),
+                                                         PathIntent.ProtectionType.FAILOVER);
+            intentList.add(frIntent);
+        } else {
+            updateFailoverGroup(intent, links);
+            updateFailoverGroup(intent, backupLinks);
+        }
+
+        return intentList;
+    }
+
+    private List<Intent> createSinglePathIntent(ConnectPoint ingressPoint,
+                                                ConnectPoint egressPoint,
+                                                PointToPointIntent intent,
+                                                List<Intent> installable) {
+        List<Link> links = new ArrayList<>();
+        Path onlyPath = getPath(intent, ingressPoint.deviceId(),
+                                egressPoint.deviceId());
+
+        List<Intent> reusableIntents = null;
+        if (installable != null) {
+            reusableIntents = filterInvalidSubIntents(installable, intent);
+            if (reusableIntents.size() == installable.size()) {
+                // all old paths are still viable
+                return installable;
+            }
+        }
+
+        // If there exists a full path from old installable intents,
+        // return the intents that comprise it.
+        if (reusableIntents != null && reusableIntents.size() > 1) {
+            return reusableIntents;
+        } else {
+            links.add(createEdgeLink(ingressPoint, true));
+            links.addAll(onlyPath.links());
+            links.add(createEdgeLink(egressPoint, false));
+
+            return asList(createPathIntent(new DefaultPath(PID, links, onlyPath.cost(),
+                                                           onlyPath.annotations()),
+                                           intent, PathIntent.ProtectionType.PRIMARY));
+        }
     }
 
     /**
@@ -85,9 +271,11 @@
      *
      * @param path   path to create an intent for
      * @param intent original intent
+     * @param type   primary or backup
      */
     private Intent createPathIntent(Path path,
-                                    PointToPointIntent intent) {
+                                    PointToPointIntent intent,
+                                    PathIntent.ProtectionType type) {
         return PathIntent.builder()
                 .appId(intent.appId())
                 .selector(intent.selector())
@@ -95,7 +283,262 @@
                 .path(path)
                 .constraints(intent.constraints())
                 .priority(intent.priority())
+                .setType(type)
                 .build();
     }
 
+    /**
+     * Gets primary port number through failover group associated
+     * with this intent.
+     */
+    private PortNumber getPrimaryPort(PointToPointIntent intent) {
+        Group group = groupService.getGroup(intent.ingressPoint().deviceId(),
+                                            makeGroupKey(intent.id()));
+        PortNumber primaryPort = null;
+        if (group != null) {
+            List<GroupBucket> buckets = group.buckets().buckets();
+            Iterator<GroupBucket> iterator = buckets.iterator();
+            while (primaryPort == null && iterator.hasNext()) {
+                GroupBucket bucket = iterator.next();
+                Instruction individualInstruction = bucket.treatment().allInstructions().get(0);
+                if (individualInstruction instanceof Instructions.OutputInstruction) {
+                    Instructions.OutputInstruction outInstruction =
+                            (Instructions.OutputInstruction) individualInstruction;
+                    PortNumber tempPortNum = outInstruction.port();
+                    Port port = deviceService.getPort(intent.ingressPoint().deviceId(),
+                                                      tempPortNum);
+                    if (port != null && port.isEnabled()) {
+                        primaryPort = tempPortNum;
+                    }
+                }
+            }
+        }
+        return primaryPort;
+    }
+
+    /**
+     * Creates group key unique to each intent.
+     */
+    public static GroupKey makeGroupKey(IntentId intentId) {
+        ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
+        buffer.putLong(intentId.fingerprint());
+        return new DefaultGroupKey(buffer.array());
+    }
+
+    /**
+     * Creates a new failover group with the initial ports of the links
+     * from the primary and backup path.
+     *
+     * @param links         links from the primary path
+     * @param backupLinks   links from the backup path
+     * @param intent        intent from which this call originates
+     */
+    private void createFailoverTreatmentGroup(List<Link> links,
+                                              List<Link> backupLinks,
+                                              PointToPointIntent intent) {
+
+        List<GroupBucket> buckets = new ArrayList<>();
+
+        TrafficTreatment.Builder tBuilderIn = DefaultTrafficTreatment.builder();
+        ConnectPoint src = links.get(0).src();
+        tBuilderIn.setOutput(src.port());
+
+        TrafficTreatment.Builder tBuilderIn2 = DefaultTrafficTreatment.builder();
+        ConnectPoint src2 = backupLinks.get(0).src();
+        tBuilderIn2.setOutput(src2.port());
+
+        buckets.add(DefaultGroupBucket.createFailoverGroupBucket(tBuilderIn.build(), src.port(), null));
+        buckets.add(DefaultGroupBucket.createFailoverGroupBucket(tBuilderIn2.build(), src2.port(), null));
+
+        GroupBuckets groupBuckets = new GroupBuckets(buckets);
+
+        GroupDescription groupDesc = new DefaultGroupDescription(src.deviceId(), Group.Type.FAILOVER,
+                                         groupBuckets, makeGroupKey(intent.id()), null, intent.appId());
+        groupService.addGroup(groupDesc);
+    }
+
+    /**
+     * Manufactures flow rule with treatment that is defined by failover
+     * group and traffic selector determined by ingress port of the intent.
+     *
+     * @param intent intent which is being compiled (for appId)
+     * @return       a list of a singular flow rule with fast failover
+     *               outport traffic treatment
+     */
+    private List<FlowRule> createFailoverFlowRules(PointToPointIntent intent) {
+        List<FlowRule> flowRules = new ArrayList<>();
+
+        ConnectPoint ingress = intent.ingressPoint();
+        DeviceId deviceId = ingress.deviceId();
+
+        // flow rule with failover traffic treatment
+        TrafficSelector trafficSelector = DefaultTrafficSelector.builder(intent.selector())
+                                                      .matchInPort(ingress.port()).build();
+
+        FlowRule.Builder flowRuleBuilder = DefaultFlowRule.builder();
+        flowRules.add(flowRuleBuilder.withSelector(trafficSelector)
+                              .withTreatment(buildFailoverTreatment(deviceId, makeGroupKey(intent.id())))
+                              .fromApp(intent.appId())
+                              .makePermanent()
+                              .forDevice(deviceId)
+                              .withPriority(PRIORITY)
+                              .build());
+
+        return flowRules;
+    }
+
+    private TrafficTreatment buildFailoverTreatment(DeviceId srcDevice,
+                                                    GroupKey groupKey) {
+        Group group = groupService.getGroup(srcDevice, groupKey);
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        TrafficTreatment trafficTreatment = tBuilder.group(group.id()).build();
+        return trafficTreatment;
+    }
+
+    /**
+     * Deletes intents from the given list if the ports or links the intent
+     * relies on are no longer viable. The failover flow rule intent is never
+     * deleted -- only its contents are updated.
+     *
+     * @param oldInstallables  list of intents to examine
+     * @return                 list of reusable installable intents
+     */
+    private List<Intent> filterInvalidSubIntents(List<Intent> oldInstallables,
+                                                 PointToPointIntent pointIntent) {
+        List<Intent> intentList = new ArrayList<>();
+        intentList.addAll(oldInstallables);
+        erasePrimary = false;
+        eraseBackup = false;
+        if (intentList != null) {
+            Iterator<Intent> iterator = intentList.iterator();
+            while (iterator.hasNext() && !(erasePrimary && eraseBackup)) {
+                Intent intent = iterator.next();
+                intent.resources().forEach(resource -> {
+                    if (resource instanceof Link) {
+                        Link link = (Link) resource;
+                        if (link.state() == Link.State.INACTIVE) {
+                            setPathsToRemove(intent);
+                        } else if (link instanceof EdgeLink) {
+                            ConnectPoint connectPoint = (link.src().elementId() instanceof DeviceId)
+                                    ? link.src() : link.dst();
+                            Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port());
+                            if (port == null || !port.isEnabled()) {
+                                setPathsToRemove(intent);
+                            }
+                        } else {
+                            Port port1 = deviceService.getPort(link.src().deviceId(), link.src().port());
+                            Port port2 = deviceService.getPort(link.dst().deviceId(), link.dst().port());
+                            if (port1 == null || !port1.isEnabled() || port2 == null || !port2.isEnabled()) {
+                                setPathsToRemove(intent);
+                            }
+                        }
+                    }
+                });
+            }
+            removeAndUpdateIntents(intentList, pointIntent);
+        }
+        return intentList;
+    }
+
+    /**
+     * Sets instance variables erasePrimary and eraseBackup. If erasePrimary,
+     * the primary path is no longer viable and related intents will be deleted.
+     * If eraseBackup, the backup path is no longer viable and related intents
+     * will be deleted.
+     *
+     * @param intent  intent whose resources are found to be disabled/inactive:
+     *                if intent is part of primary path, primary path set for removal;
+     *                if intent is part of backup path, backup path set for removal;
+     *                if bad intent is of type failover, the ingress point is down,
+     *                and both paths are rendered inactive.
+     * @return        true if both primary and backup paths are to be removed
+     */
+    private boolean setPathsToRemove(Intent intent) {
+        if (intent instanceof FlowRuleIntent) {
+            FlowRuleIntent frIntent = (FlowRuleIntent) intent;
+            PathIntent.ProtectionType type = frIntent.type();
+            if (type == PathIntent.ProtectionType.PRIMARY || type == PathIntent.ProtectionType.FAILOVER) {
+                erasePrimary = true;
+            }
+            if (type == PathIntent.ProtectionType.BACKUP || type == PathIntent.ProtectionType.FAILOVER) {
+                eraseBackup = true;
+            }
+        }
+        return erasePrimary && eraseBackup;
+    }
+
+    /**
+     * Removes intents from installables list, depending on the values
+     * of instance variables erasePrimary and eraseBackup. Flow rule intents
+     * that contain the manufactured fast failover flow rules are never deleted.
+     * The contents are simply modified as necessary. If cleanUpIntents size
+     * is greater than 1 (failover intent), then one whole path from previous
+     * installables must be still viable.
+     *
+     * @param cleanUpIntents   list of installable intents
+     */
+    private void removeAndUpdateIntents(List<Intent> cleanUpIntents,
+                                        PointToPointIntent pointIntent) {
+        ListIterator<Intent> iterator = cleanUpIntents.listIterator();
+        while (iterator.hasNext()) {
+            Intent cIntent = iterator.next();
+            if (cIntent instanceof FlowRuleIntent) {
+                FlowRuleIntent fIntent = (FlowRuleIntent) cIntent;
+                if (fIntent.type() == PathIntent.ProtectionType.PRIMARY && erasePrimary) {
+                    // remove primary path's flow rule intents
+                    iterator.remove();
+                } else if (fIntent.type() == PathIntent.ProtectionType.BACKUP && eraseBackup) {
+                    //remove backup path's flow rule intents
+                    iterator.remove();
+                } else if (fIntent.type() == PathIntent.ProtectionType.BACKUP && erasePrimary) {
+                    // promote backup path's flow rule intents to primary
+                    iterator.set(new FlowRuleIntent(fIntent, PathIntent.ProtectionType.PRIMARY));
+                }
+            }
+        }
+        // remove buckets whose watchports are disabled if the failover group exists
+        Group group = groupService.getGroup(pointIntent.ingressPoint().deviceId(),
+                                            makeGroupKey(pointIntent.id()));
+        if (group != null) {
+            updateFailoverGroup(pointIntent);
+        }
+    }
+
+    // Removes buckets whose treatments rely on disabled ports from the
+    // failover group.
+    private void updateFailoverGroup(PointToPointIntent pointIntent) {
+        DeviceId deviceId = pointIntent.ingressPoint().deviceId();
+        GroupKey groupKey = makeGroupKey(pointIntent.id());
+        Group group = groupService.getGroup(deviceId, groupKey);
+        Iterator<GroupBucket> groupIterator = group.buckets().buckets().iterator();
+        while (groupIterator.hasNext()) {
+            GroupBucket bucket = groupIterator.next();
+            Instruction individualInstruction = bucket.treatment().allInstructions().get(0);
+            if (individualInstruction instanceof Instructions.OutputInstruction) {
+                Instructions.OutputInstruction outInstruction =
+                        (Instructions.OutputInstruction) individualInstruction;
+                Port port = deviceService.getPort(deviceId, outInstruction.port());
+                if (port == null || !port.isEnabled()) {
+                    GroupBuckets removeBuckets = new GroupBuckets(Collections.singletonList(bucket));
+                    groupService.removeBucketsFromGroup(deviceId, groupKey,
+                                                        removeBuckets, groupKey,
+                                                        pointIntent.appId());
+                }
+            }
+        }
+    }
+
+    // Adds failover group bucket with treatment outport determined by the
+    // ingress point of the links.
+    private void updateFailoverGroup(PointToPointIntent intent, List<Link> links) {
+        GroupKey groupKey = makeGroupKey(intent.id());
+
+        TrafficTreatment.Builder tBuilderIn = DefaultTrafficTreatment.builder();
+        ConnectPoint src = links.get(0).src();
+        tBuilderIn.setOutput(src.port());
+        GroupBucket bucket = DefaultGroupBucket.createFailoverGroupBucket(tBuilderIn.build(), src.port(), null);
+        GroupBuckets addBuckets = new GroupBuckets(Collections.singletonList(bucket));
+
+        groupService.addBucketsToGroup(src.deviceId(), groupKey, addBuckets, groupKey, intent.appId());
+    }
 }
