diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
new file mode 100644
index 0000000..d493773
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
@@ -0,0 +1,241 @@
+package org.onosproject.vpls;
+
+import com.google.common.collect.SetMultimap;
+import javafx.util.Pair;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+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.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.SinglePointToMultiPointIntent;
+import org.onosproject.routing.IntentSynchronizationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+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 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 final ApplicationId appId;
+    private final IntentSynchronizationService intentSynchronizer;
+    private final IntentService intentService;
+
+    /**
+     * Class constructor.
+     *
+     * @param appId              the Application ID
+     * @param intentService      the intent service
+     * @param intentSynchronizer the intent synchronizer service
+     */
+    public IntentInstaller(ApplicationId appId, IntentService intentService,
+                           IntentSynchronizationService intentSynchronizer) {
+        this.appId = appId;
+        this.intentService = intentService;
+        this.intentSynchronizer = intentSynchronizer;
+    }
+
+    /**
+     * Formats the requests for creating and submit intents.
+     * Single Points to Multi Point intents are created for all the conigured
+     * 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.asMap().keySet()
+                .forEach(vlanId -> {
+                    List<Pair<ConnectPoint, MacAddress>> cPoints =
+                            confHostPresentCPoint.get(vlanId).stream().collect(Collectors.toList());
+
+                    if (cPoints != null && !cPoints.isEmpty()) {
+                        for (int i = 0; i < cPoints.size(); i++) {
+                            ConnectPoint src = cPoints.get(i).getKey();
+                            Set<ConnectPoint> dsts = new HashSet<>();
+                            MacAddress mac = cPoints.get(i).getValue();
+                            for (int j = 0; j < cPoints.size(); j++) {
+                                ConnectPoint dst = cPoints.get(j).getKey();
+                                if (!dst.equals(src)) {
+                                    dsts.add(dst);
+                                }
+                            }
+                            Key brcKey = buildKey(PREFIX_BROADCAST, src, vlanId);
+                            if (intentService.getIntent(brcKey) == null) {
+                                SinglePointToMultiPointIntent brcIntent =
+                                        buildBrcIntent(brcKey, src, dsts, vlanId);
+                                intents.add(brcIntent);
+                            }
+                            if (mac != null && countMacInCPoints(cPoints) > 1) {
+                                Key uniKey = buildKey(PREFIX_UNICAST, src, vlanId);
+                                if (intentService.getIntent(uniKey) == null) {
+                                    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 IntentSynchronizer");
+
+        for (Intent intent : intents) {
+            intentSynchronizer.submit(intent);
+        }
+    }
+
+    /**
+     * Builds a Single Point to Multi Point intent.
+     *
+     * @param src  The source Connect Point
+     * @param dsts The destination Connect Points
+     * @return Single Point to Multi Point intent generated.
+     */
+    private SinglePointToMultiPointIntent buildBrcIntent(Key key,
+                                                         ConnectPoint src,
+                                                         Set<ConnectPoint> dsts,
+                                                         VlanId vlanId) {
+        log.debug("Building p2mp intent from {}", src);
+
+        SinglePointToMultiPointIntent intent;
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+
+        TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
+                .matchEthDst(MacAddress.BROADCAST)
+                .matchVlanId(vlanId);
+
+        TrafficSelector selector = builder.build();
+
+        intent = SinglePointToMultiPointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(src)
+                .egressPoints(dsts)
+                .priority(PRIORITY_OFFSET)
+                .build();
+        return intent;
+    }
+
+    /**
+     * Builds a Multi Point to Single Point intent.
+     *
+     * @param srcs The source Connect Points
+     * @param dst  The destination Connect Point
+     * @return Multi Point to Single Point intent generated.
+     */
+    private MultiPointToSinglePointIntent buildUniIntent(Key key,
+                                                         Set<ConnectPoint> srcs,
+                                                         ConnectPoint dst,
+                                                         VlanId vlanId,
+                                                         MacAddress mac) {
+        log.debug("Building mp2p intent to {}", dst);
+
+        MultiPointToSinglePointIntent intent;
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+
+        TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
+                .matchEthDst(mac)
+                .matchVlanId(vlanId);
+
+        TrafficSelector selector = builder.build();
+
+        intent = MultiPointToSinglePointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoints(srcs)
+                .egressPoint(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
+     * the type of intent, the single connection point representing the source
+     * or the destination and the vlan id representing the network.
+     *
+     * @param cPoint the source or destination connect point
+     * @param vlanId the network vlan id
+     * @param prefix prefix string
+     * @return
+     */
+    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();
+
+        return Key.of(keyString, appId);
+    }
+
+    /**
+     * Counts the number of mac addresses associated to a specific list of
+     * ConnectPoint.
+     *
+     * @param cPoints List of ConnectPoints, eventually binded to the MAC of the
+     *                host attached
+     * @return number of mac addresses found.
+     */
+    private int countMacInCPoints(List<Pair<ConnectPoint, MacAddress>> cPoints) {
+        int macFound = 0;
+        for (Pair<ConnectPoint, MacAddress> p : cPoints) {
+            if (p.getValue() != null) {
+                macFound++;
+            }
+        }
+        return macFound;
+    }
+
+}
