diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
index 79ed713..52a3924 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
@@ -15,18 +15,18 @@
  */
 package org.onosproject.vpls;
 
-import com.google.common.collect.SetMultimap;
-import org.apache.commons.lang3.tuple.Pair;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
 import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Host;
 import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentState;
 import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
 import org.onosproject.net.intent.SinglePointToMultiPointIntent;
@@ -34,24 +34,37 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * Synchronizes intents between the in-memory intent store and the
  * IntentService.
  */
 public class IntentInstaller {
+    private static final String SUBMIT =
+            "Submitting intents to the Intent Synchronizer";
+    private static final String WITHDRAW =
+            "Withdrawing intents to the Intent Synchronizer";
+    private static final String SP2MP =
+            "Building sp2mp intent from {}";
+    private static final String MP2SP =
+            "Building mp2sp intent to {}";
+
     private static final Logger log = LoggerFactory.getLogger(
             IntentInstaller.class);
 
     private static final int PRIORITY_OFFSET = 1000;
 
-    private static final String PREFIX_BROADCAST = "brc";
-    private static final String PREFIX_UNICAST = "uni";
+    private static final Set<IntentState> WITHDRAWN_INTENT_STATES =
+            ImmutableSet.of(IntentState.WITHDRAWN,
+                            IntentState.WITHDRAW_REQ,
+                            IntentState.WITHDRAWING);
+
+    static final String PREFIX_BROADCAST = "brc";
+    static final String PREFIX_UNICAST = "uni";
+    static final String DASH = "-";
 
     private final ApplicationId appId;
     private final IntentSynchronizationService intentSynchronizer;
@@ -72,173 +85,150 @@
     }
 
     /**
-     * Formats the requests for creating and submit intents.
-     * Single Points to Multi Point intents are created for all the configured
-     * Connect Points. Multi Point to Single Point intents are created for
-     * Connect Points configured that have hosts attached.
-     *
-     * @param confHostPresentCPoint A map of Connect Points with the eventual
-     *                              MAC address of the host attached, by VLAN
-     */
-    protected void installIntents(SetMultimap<VlanId,
-            Pair<ConnectPoint,
-                    MacAddress>> confHostPresentCPoint) {
-        List<Intent> intents = new ArrayList<>();
-
-        confHostPresentCPoint.keySet()
-                .stream()
-                .filter(vlanId -> confHostPresentCPoint.get(vlanId) != null)
-                .forEach(vlanId -> {
-                    Set<Pair<ConnectPoint, MacAddress>> cPoints =
-                            confHostPresentCPoint.get(vlanId);
-                    cPoints.forEach(cPoint -> {
-                        MacAddress mac = cPoint.getValue();
-                        ConnectPoint src = cPoint.getKey();
-                        Set<ConnectPoint> dsts = cPoints.stream()
-                                .map(Pair::getKey)
-                                .filter(cp -> !cp.equals(src))
-                                .collect(Collectors.toSet());
-                        Key brcKey = buildKey(PREFIX_BROADCAST, src, vlanId);
-
-                        if (dsts.isEmpty()) {
-                            return;
-                        }
-
-                        intents.add(buildBrcIntent(brcKey, src, dsts, vlanId));
-
-                        if (mac != null && countMacInCPoints(cPoints) > 1) {
-                            Key uniKey = buildKey(PREFIX_UNICAST, src, vlanId);
-                            MultiPointToSinglePointIntent uniIntent =
-                                    buildUniIntent(uniKey,
-                                                   dsts,
-                                                   src,
-                                                   vlanId,
-                                                   mac);
-                            intents.add(uniIntent);
-                        }
-                    });
-                });
-        submitIntents(intents);
-    }
-
-    /**
      * Requests to install the intents passed as argument to the Intent Service.
      *
      * @param intents intents to be submitted
      */
-    private void submitIntents(Collection<Intent> intents) {
-        log.debug("Submitting intents to the Intent Synchronizer");
-        intents.forEach(intent -> {
-            intentSynchronizer.submit(intent);
-        });
+    protected void submitIntents(Collection<Intent> intents) {
+        log.debug(SUBMIT);
+        intents.forEach(intentSynchronizer::submit);
     }
 
     /**
-     * Builds a Single Point to Multi Point intent.
+     * Requests to withdraw the intents passed as argument to the Intent Service.
      *
-     * @param src  The source Connect Point
-     * @param dsts The destination Connect Points
-     * @return Single Point to Multi Point intent generated.
+     * @param intents intents to be withdraw
      */
-    private SinglePointToMultiPointIntent buildBrcIntent(Key key,
-                                                         ConnectPoint src,
-                                                         Set<ConnectPoint> dsts,
-                                                         VlanId vlanId) {
-        log.debug("Building p2mp intent from {}", src);
+    protected void withdrawIntents(Collection<Intent> intents) {
+        log.debug(WITHDRAW);
+        intents.forEach(intentSynchronizer::withdraw);
+    }
+
+    /**
+     * Returns list of intents belongs to a VPLS.
+     *
+     * @param name required VPLS network name
+     * @return list of intents belongs to a VPLS
+     */
+    protected List<Intent> getIntentsFromVpls(String name) {
+        List<Intent> intents = Lists.newArrayList();
+
+        intentService.getIntents().forEach(intent -> {
+            if (intent.key().toString().startsWith(name)) {
+                intents.add(intent);
+            }
+        });
+
+        return intents;
+    }
+
+    /**
+     * Builds a broadcast intent.
+     *
+     * @param key key to identify the intent
+     * @param src the source connect point
+     * @param dsts the destination connect points
+     * @return the generated single-point to multi-point intent
+     */
+    protected SinglePointToMultiPointIntent buildBrcIntent(Key key,
+                                                           FilteredConnectPoint src,
+                                                           Set<FilteredConnectPoint> dsts) {
+        log.debug(SP2MP, src);
 
         SinglePointToMultiPointIntent intent;
 
-        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
-
-        TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
+        TrafficSelector selector = DefaultTrafficSelector.builder()
                 .matchEthDst(MacAddress.BROADCAST)
-                .matchVlanId(vlanId);
-
-        TrafficSelector selector = builder.build();
+                .build();
 
         intent = SinglePointToMultiPointIntent.builder()
                 .appId(appId)
                 .key(key)
                 .selector(selector)
-                .treatment(treatment)
-                .ingressPoint(src)
-                .egressPoints(dsts)
+                .filteredIngressPoint(src)
+                .filteredEgressPoints(dsts)
                 .priority(PRIORITY_OFFSET)
                 .build();
         return intent;
     }
 
     /**
-     * Builds a Multi Point to Single Point intent.
+     * Builds a unicast intent.
      *
-     * @param srcs The source Connect Points
-     * @param dst  The destination Connect Point
-     * @return Multi Point to Single Point intent generated.
+     * @param key key to identify the intent
+     * @param srcs the source Connect Points
+     * @param dst the destination Connect Point
+     * @param host destination Host
+     * @return the generated multi-point to single-point intent
      */
-    private MultiPointToSinglePointIntent buildUniIntent(Key key,
-                                                         Set<ConnectPoint> srcs,
-                                                         ConnectPoint dst,
-                                                         VlanId vlanId,
-                                                         MacAddress mac) {
-        log.debug("Building mp2p intent to {}", dst);
+    protected MultiPointToSinglePointIntent buildUniIntent(Key key,
+                                                           Set<FilteredConnectPoint> srcs,
+                                                           FilteredConnectPoint dst,
+                                                           Host host) {
+        log.debug(MP2SP, dst);
 
-        MultiPointToSinglePointIntent intent;
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthDst(host.mac())
+                .build();
 
-        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
 
-        TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
-                .matchEthDst(mac)
-                .matchVlanId(vlanId);
-
-        TrafficSelector selector = builder.build();
-
-        intent = MultiPointToSinglePointIntent.builder()
+        return MultiPointToSinglePointIntent.builder()
                 .appId(appId)
                 .key(key)
                 .selector(selector)
-                .treatment(treatment)
-                .ingressPoints(srcs)
-                .egressPoint(dst)
+                .filteredIngressPoints(srcs)
+                .filteredEgressPoint(dst)
                 .priority(PRIORITY_OFFSET)
                 .build();
-        return intent;
+
     }
 
     /**
-     * Builds an intent Key for either for a Single Point to Multi Point or
-     * Multi Point to Single Point intent, based on a prefix that defines
+     * Builds an intent Key for either for a single-point to multi-point or
+     * multi-point to single-point intent, based on a prefix that defines
      * the type of intent, the single connection point representing the source
-     * or the destination and the vlan id representing the network.
+     * or the destination and the VLAN identifier representing the network.
      *
-     * @param cPoint the source or destination connect point
-     * @param vlanId the network vlan id
-     * @param prefix prefix string
-     * @return
+     * @param prefix key prefix
+     * @param cPoint connect point for single source/destination
+     * @param networkName VPLS network name
+     * @param hostMac source/destination mac address
+     * @return key to identify the intent
      */
-    private Key buildKey(String prefix, ConnectPoint cPoint, VlanId vlanId) {
-        String keyString = new StringBuilder()
-                .append(prefix)
-                .append("-")
-                .append(cPoint.deviceId())
-                .append("-")
-                .append(cPoint.port())
-                .append("-")
-                .append(vlanId)
-                .toString();
+    protected Key buildKey(String prefix,
+                           ConnectPoint cPoint,
+                           String networkName,
+                           MacAddress hostMac) {
+        String keyString = networkName +
+                DASH +
+                prefix +
+                DASH +
+                cPoint.deviceId() +
+                DASH +
+                cPoint.port() +
+                DASH +
+                hostMac;
 
         return Key.of(keyString, appId);
     }
 
     /**
-     * Counts the number of mac addresses associated to a specific list of
-     * ConnectPoint.
+     * Returns true if the specified intent exists; false otherwise.
      *
-     * @param cPoints Set of ConnectPoints, eventually bound to the MAC of the
-     *                host attached
-     * @return number of mac addresses found.
+     * @param intentKey intent key
+     * @return true if the intent exists, false otherwise
      */
-    private int countMacInCPoints(Set<Pair<ConnectPoint, MacAddress>> cPoints) {
-        return (int) cPoints.stream().filter(p -> p.getValue() != null).count();
-    }
+    protected boolean intentExists(Key intentKey) {
+        if (intentService.getIntent(intentKey) == null) {
+            return false;
+        }
 
+        // Intent does not exist if intent withdrawn
+        IntentState currentIntentState = intentService.getIntentState(intentKey);
+        if (WITHDRAWN_INTENT_STATES.contains(currentIntentState)) {
+            return false;
+        }
+
+        return true;
+    }
 }
