diff --git a/apps/intentsync/BUCK b/apps/intentsync/BUCK
new file mode 100644
index 0000000..685cd74
--- /dev/null
+++ b/apps/intentsync/BUCK
@@ -0,0 +1,22 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:org.apache.karaf.shell.console',
+    '//cli:onos-cli'
+]
+
+TEST_DEPS = [
+    '//lib:TEST_ADAPTERS',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
+)
+
+onos_app (
+  app_name = 'org.onosproject.intentsynchronizer',
+  title = 'Intent Synchronizer',
+  category = 'Utility',
+  url = 'http://onosproject.org',
+  description = 'Synchronizes intents to the intent framework from a single instance',
+)
diff --git a/apps/intentsync/pom.xml b/apps/intentsync/pom.xml
new file mode 100644
index 0000000..895504e
--- /dev/null
+++ b/apps/intentsync/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>onos-apps</artifactId>
+        <groupId>org.onosproject</groupId>
+        <version>1.9.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>onos-apps-intentsync</artifactId>
+    <packaging>bundle</packaging>
+
+    <properties>
+        <onos.app.name>org.onosproject.intentsynchronizer</onos.app.name>
+        <onos.app.title>Intent Synchronizer</onos.app.title>
+        <onos.app.category>Utility</onos.app.category>
+        <onos.app.url>http://onosproject.org</onos.app.url>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <scope>test</scope>
+            <classifier>tests</classifier>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationAdminService.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationAdminService.java
new file mode 100644
index 0000000..5d42046
--- /dev/null
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationAdminService.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.intentsync;
+
+/**
+ * Administrative APIs for managing intent synchronization.
+ */
+public interface IntentSynchronizationAdminService {
+
+    /**
+     * Changes whether this instance is the primary or not based on the
+     * boolean parameter.
+     *
+     * @param isPrimary true if the instance is primary, false if it is not
+     */
+    void modifyPrimary(boolean isPrimary);
+
+    /**
+     * Withdraws all intents.
+     */
+    void removeIntents();
+}
diff --git a/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationService.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationService.java
new file mode 100644
index 0000000..e027d69
--- /dev/null
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationService.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.intentsync;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.intent.Intent;
+
+/**
+ * Submits and withdraws intents to the IntentService from a single point in
+ * the cluster at any one time. The provided intents will be synchronized with
+ * the IntentService on leadership change.
+ * <p>
+ * This is a sample utility and not part of the core ONOS API. This means it is
+ * subject to change or to be removed. It is recommended to consider using one
+ * of the built-in ONOS distributed primitives such as the
+ * {@link org.onosproject.store.service.WorkQueue} instead of using this.
+ * </p>
+ */
+public interface IntentSynchronizationService {
+
+    /**
+     * Submits and intent to the synchronizer.
+     * <p>
+     * The intent will be submitted directly to the IntentService if this node
+     * is the leader, otherwise it will be stored in the synchronizer for
+     * synchronization if this node becomes the leader.
+     * </p>
+     *
+     * @param intent intent to submit
+     */
+    void submit(Intent intent);
+
+    /**
+     * Withdraws an intent from the synchronizer.
+     * <p>
+     * The intent will be withdrawn directly from the IntentService if this node
+     * is the leader. The intent will be removed from the synchronizer's
+     * in-memory storage.
+     * </p>
+     *
+     * @param intent intent to withdraw
+     */
+    void withdraw(Intent intent);
+
+    /**
+     * Withdraws intents by app Id.
+     *
+     * @param applicationId the Id of the application that created the intents
+     *                      to be removed
+     */
+    void removeIntentsByAppId(ApplicationId applicationId);
+}
diff --git a/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizer.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizer.java
new file mode 100644
index 0000000..def8172
--- /dev/null
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizer.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.intentsync;
+
+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.apache.felix.scr.annotations.Service;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipEvent;
+import org.onosproject.cluster.LeadershipEventListener;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.IntentUtils;
+import org.onosproject.net.intent.Key;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * Synchronizes intents between an in-memory intent store and the IntentService.
+ */
+@Service
+@Component(immediate = true)
+public class IntentSynchronizer implements IntentSynchronizationService,
+        IntentSynchronizationAdminService {
+
+    private static final Logger log = LoggerFactory.getLogger(IntentSynchronizer.class);
+
+    private static final String APP_NAME = "org.onosproject.intentsynchronizer";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LeadershipService leadershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentService intentService;
+
+    private NodeId localNodeId;
+    private ApplicationId appId;
+
+    private final InternalLeadershipListener leadershipEventListener =
+            new InternalLeadershipListener();
+
+    private final Map<Key, Intent> intents = new ConcurrentHashMap<>();
+
+    private ExecutorService intentsSynchronizerExecutor;
+
+    private volatile boolean isElectedLeader = false;
+    private volatile boolean isActivatedLeader = false;
+
+    @Activate
+    public void activate() {
+        this.localNodeId = clusterService.getLocalNode().id();
+        this.appId = coreService.registerApplication(APP_NAME);
+        intentsSynchronizerExecutor = createExecutor();
+
+        leadershipService.addListener(leadershipEventListener);
+        leadershipService.runForLeadership(appId.name());
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        leadershipService.withdraw(appId.name());
+        leadershipService.removeListener(leadershipEventListener);
+
+        synchronized (this) {
+            intentsSynchronizerExecutor.shutdownNow();
+        }
+
+        log.info("Stopped");
+    }
+
+    /**
+     * Creates an executor that will be used for synchronization tasks.
+     * <p>
+     * Can be overridden to change the type of executor used.
+     * </p>
+     *
+     * @return executor service
+     */
+    protected ExecutorService createExecutor() {
+        return newSingleThreadExecutor(groupedThreads("onos/" + appId, "sync", log));
+    }
+
+    @Override
+    public void removeIntents() {
+        if (!isElectedLeader) {
+            // Only leader will withdraw intents
+            return;
+        }
+
+        log.debug("Intent Synchronizer shutdown: withdrawing all intents...");
+
+        for (Entry<Key, Intent> entry : intents.entrySet()) {
+            intentService.withdraw(entry.getValue());
+            log.debug("Intent Synchronizer withdrawing intent: {}",
+                      entry.getValue());
+        }
+
+        intents.clear();
+        log.info("Tried to clean all intents");
+    }
+
+    @Override
+    public void removeIntentsByAppId(ApplicationId appId) {
+        if (!isElectedLeader) {
+            // Only leader will withdraw intents
+            return;
+        }
+
+        log.debug("Withdrawing intents for app {}...",
+                  appId);
+
+        intents.entrySet()
+                .stream()
+                .filter(intent -> intent.getValue().appId().equals(appId))
+                .forEach(intent -> {
+                    log.debug("Intent Synchronizer withdrawing intent: {}",
+                              intent);
+                    intentService.withdraw(intent.getValue());
+                    intents.remove(intent.getKey(), intent.getValue());
+                    log.info("Tried to clean intents for app: {}", appId);
+                });
+    }
+
+    @Override
+    public void submit(Intent intent) {
+        synchronized (this) {
+            intents.put(intent.key(), intent);
+            if (isElectedLeader && isActivatedLeader) {
+                log.trace("Submitting intent: {}", intent);
+                intentService.submit(intent);
+            }
+        }
+    }
+
+    @Override
+    public void withdraw(Intent intent) {
+        synchronized (this) {
+            intents.remove(intent.key(), intent);
+            if (isElectedLeader && isActivatedLeader) {
+                log.trace("Withdrawing intent: {}", intent);
+                intentService.withdraw(intent);
+            }
+        }
+    }
+
+    /**
+     * Signals the synchronizer that the leadership has changed.
+     *
+     * @param isLeader true if this instance is now the leader, otherwise false
+     */
+    private void leaderChanged(boolean isLeader) {
+        log.debug("Leader changed: {}", isLeader);
+
+        if (!isLeader) {
+            this.isElectedLeader = false;
+            this.isActivatedLeader = false;
+            // Nothing to do
+            return;
+        }
+        this.isActivatedLeader = false;
+        this.isElectedLeader = true;
+
+        // Run the synchronization task
+        intentsSynchronizerExecutor.execute(this::synchronizeIntents);
+    }
+
+    private void synchronizeIntents() {
+        Map<Key, Intent> serviceIntents = new HashMap<>();
+        intentService.getIntents().forEach(i -> {
+            if (i.appId().equals(appId)) {
+                serviceIntents.put(i.key(), i);
+            }
+        });
+
+        List<Intent> intentsToAdd = new LinkedList<>();
+        List<Intent> intentsToRemove = new LinkedList<>();
+
+        for (Intent localIntent : intents.values()) {
+            Intent serviceIntent = serviceIntents.remove(localIntent.key());
+            if (serviceIntent == null) {
+                intentsToAdd.add(localIntent);
+            } else {
+                IntentState state = intentService.getIntentState(serviceIntent.key());
+                if (!IntentUtils.intentsAreEqual(serviceIntent, localIntent) || state == null ||
+                        state == IntentState.WITHDRAW_REQ ||
+                        state == IntentState.WITHDRAWING ||
+                        state == IntentState.WITHDRAWN) {
+                    intentsToAdd.add(localIntent);
+                }
+            }
+        }
+
+        for (Intent serviceIntent : serviceIntents.values()) {
+            IntentState state = intentService.getIntentState(serviceIntent.key());
+            if (state != null && state != IntentState.WITHDRAW_REQ
+                    && state != IntentState.WITHDRAWING
+                    && state != IntentState.WITHDRAWN) {
+                intentsToRemove.add(serviceIntent);
+            }
+        }
+
+        log.debug("Intent Synchronizer: submitting {}, withdrawing {}",
+                intentsToAdd.size(), intentsToRemove.size());
+
+        // Withdraw Intents
+        for (Intent intent : intentsToRemove) {
+            intentService.withdraw(intent);
+            log.trace("Intent Synchronizer: withdrawing intent: {}",
+                    intent);
+        }
+        if (!isElectedLeader) {
+            log.debug("Intent Synchronizer: cannot withdraw intents: " +
+                    "not elected leader anymore");
+            isActivatedLeader = false;
+            return;
+        }
+
+        // Add Intents
+        for (Intent intent : intentsToAdd) {
+            intentService.submit(intent);
+            log.trace("Intent Synchronizer: submitting intent: {}",
+                    intent);
+        }
+        if (!isElectedLeader) {
+            log.debug("Intent Synchronizer: cannot submit intents: " +
+                    "not elected leader anymore");
+            isActivatedLeader = false;
+            return;
+        }
+
+        if (isElectedLeader) {
+            // Allow push of Intents
+            isActivatedLeader = true;
+        } else {
+            isActivatedLeader = false;
+        }
+        log.debug("Intent synchronization completed");
+    }
+
+    @Override
+    public void modifyPrimary(boolean isPrimary) {
+        leaderChanged(isPrimary);
+    }
+
+    /**
+     * A listener for leadership events.
+     */
+    private class InternalLeadershipListener implements LeadershipEventListener {
+
+        @Override
+        public boolean isRelevant(LeadershipEvent event) {
+            return event.subject().topic().equals(appId.name());
+        }
+
+        @Override
+        public void event(LeadershipEvent event) {
+            switch (event.type()) {
+            case LEADER_CHANGED:
+            case LEADER_AND_CANDIDATES_CHANGED:
+                if (localNodeId.equals(event.subject().leaderNodeId())) {
+                    log.info("IntentSynchronizer gained leadership");
+                    leaderChanged(true);
+                } else {
+                    log.info("IntentSynchronizer leader changed. New leader is {}", event.subject().leaderNodeId());
+                    leaderChanged(false);
+                }
+            default:
+                break;
+            }
+        }
+    }
+}
diff --git a/apps/intentsync/src/main/java/org/onosproject/intentsync/cli/PrimaryChangeCommand.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/cli/PrimaryChangeCommand.java
new file mode 100644
index 0000000..16898b2
--- /dev/null
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/cli/PrimaryChangeCommand.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.intentsync.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.intentsync.IntentSynchronizationAdminService;
+
+/**
+ * Command to change whether this instance's intent synchronizer is primary.
+ */
+@Command(scope = "onos", name = "sdnip-set-primary",
+         description = "Changes the primary status of this SDN-IP instance")
+public class PrimaryChangeCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "isPrimary",
+            description = "True if this instance should be primary, false if not",
+            required = true, multiValued = false)
+    boolean isPrimary = false;
+
+    @Override
+    protected void execute() {
+        AbstractShellCommand.get(IntentSynchronizationAdminService.class).modifyPrimary(isPrimary);
+    }
+
+}
diff --git a/apps/intentsync/src/main/java/org/onosproject/intentsync/cli/package-info.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/cli/package-info.java
new file mode 100644
index 0000000..53d4b7e
--- /dev/null
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Intent synchronizer CLI.
+ */
+package org.onosproject.intentsync.cli;
diff --git a/apps/intentsync/src/main/java/org/onosproject/intentsync/package-info.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/package-info.java
new file mode 100644
index 0000000..5215e6f
--- /dev/null
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Intent synchronizer.
+ */
+package org.onosproject.intentsync;
diff --git a/apps/intentsync/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/intentsync/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..b100dae
--- /dev/null
+++ b/apps/intentsync/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ Copyright 2017-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+  <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+    <command>
+      <action class="org.onosproject.intentsync.cli.PrimaryChangeCommand"/>
+    </command>
+  </command-bundle>
+</blueprint>
diff --git a/apps/intentsync/src/main/test/org/onosproject/intentsync/IntentSynchronizerTest.java b/apps/intentsync/src/main/test/org/onosproject/intentsync/IntentSynchronizerTest.java
new file mode 100644
index 0000000..860dec8
--- /dev/null
+++ b/apps/intentsync/src/main/test/org/onosproject/intentsync/IntentSynchronizerTest.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.intentsync;
+
+import com.google.common.util.concurrent.MoreExecutors;
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.TestApplicationId;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.DefaultControllerNode;
+import org.onosproject.cluster.LeadershipServiceAdapter;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+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.AbstractIntentTest;
+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 java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * This class tests the intent synchronization function in the
+ * IntentSynchronizer class.
+ */
+public class IntentSynchronizerTest extends AbstractIntentTest {
+
+    private IntentService intentService;
+
+    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000001"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000002"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000003"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000004"),
+            PortNumber.portNumber(1));
+
+    private IntentSynchronizer intentSynchronizer;
+    private final Set<ConnectPoint> connectPoints = new HashSet<>();
+
+    private static final ApplicationId APPID =
+            TestApplicationId.create("intent-sync-test");
+
+    private static final ControllerNode LOCAL_NODE =
+            new DefaultControllerNode(new NodeId("foo"), IpAddress.valueOf("127.0.0.1"));
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        setUpConnectPoints();
+
+        intentService = EasyMock.createMock(IntentService.class);
+
+        intentSynchronizer = new TestIntentSynchronizer();
+
+        intentSynchronizer.coreService = new TestCoreService();
+        intentSynchronizer.clusterService = new TestClusterService();
+        intentSynchronizer.leadershipService = new LeadershipServiceAdapter();
+        intentSynchronizer.intentService = intentService;
+
+        intentSynchronizer.activate();
+    }
+
+    /**
+     * Sets up connect points.
+     */
+    private void setUpConnectPoints() {
+        connectPoints.add(SW1_ETH1);
+        connectPoints.add(SW2_ETH1);
+        connectPoints.add(SW3_ETH1);
+        connectPoints.add(SW4_ETH1);
+    }
+
+    /**
+     * Tests the synchronization behavior of intent synchronizer. We set up
+     * a discrepancy between the intent service state and the intent
+     * synchronizer's state and ensure that this is reconciled correctly.
+     */
+    @Test
+    public void testIntentSync() {
+
+        // Construct routes and intents.
+        // This test simulates the following cases during the master change
+        // time interval:
+        // 1. intent1 did not change and the intent also did not change.
+        // 2. intent2 was deleted, but the intent was not deleted.
+        // 3. intent3 was newly added, and the intent was also submitted.
+        // 4. intent4 was updated to RouteEntry4Update, and the intent was
+        // also updated to a new one.
+        // 5. intent5 did not change, but its intent id changed.
+        // 6. intent6 was newly added, but the intent was not submitted.
+
+        MultiPointToSinglePointIntent intent1 = intentBuilder(
+                Ip4Prefix.valueOf("1.1.1.0/24"), "00:00:00:00:00:01", SW1_ETH1);
+        MultiPointToSinglePointIntent intent2 = intentBuilder(
+                Ip4Prefix.valueOf("2.2.2.0/24"), "00:00:00:00:00:02", SW2_ETH1);
+        MultiPointToSinglePointIntent intent3 = intentBuilder(
+                Ip4Prefix.valueOf("3.3.3.0/24"), "00:00:00:00:00:03", SW3_ETH1);
+        MultiPointToSinglePointIntent intent4 = intentBuilder(
+                Ip4Prefix.valueOf("4.4.4.0/24"), "00:00:00:00:00:03", SW3_ETH1);
+        MultiPointToSinglePointIntent intent4Update = intentBuilder(
+                Ip4Prefix.valueOf("4.4.4.0/24"), "00:00:00:00:00:02", SW2_ETH1);
+        MultiPointToSinglePointIntent intent5 = intentBuilder(
+                Ip4Prefix.valueOf("5.5.5.0/24"), "00:00:00:00:00:01",  SW1_ETH1);
+        MultiPointToSinglePointIntent intent7 = intentBuilder(
+                Ip4Prefix.valueOf("7.7.7.0/24"), "00:00:00:00:00:01",  SW1_ETH1);
+
+        MultiPointToSinglePointIntent intent6 = intentBuilder(
+                Ip4Prefix.valueOf("6.6.6.0/24"), "00:00:00:00:00:01",  SW1_ETH1);
+
+        // Set up expectation
+        Set<Intent> intents = new HashSet<>();
+        intents.add(intent1);
+        EasyMock.expect(intentService.getIntentState(intent1.key()))
+                .andReturn(IntentState.INSTALLED).anyTimes();
+        intents.add(intent2);
+        EasyMock.expect(intentService.getIntentState(intent2.key()))
+                .andReturn(IntentState.INSTALLED).anyTimes();
+        intents.add(intent4);
+        EasyMock.expect(intentService.getIntentState(intent4.key()))
+                .andReturn(IntentState.INSTALLED).anyTimes();
+        intents.add(intent5);
+        EasyMock.expect(intentService.getIntentState(intent5.key()))
+                .andReturn(IntentState.INSTALLED).anyTimes();
+        intents.add(intent7);
+        EasyMock.expect(intentService.getIntentState(intent7.key()))
+                .andReturn(IntentState.WITHDRAWING).anyTimes();
+        EasyMock.expect(intentService.getIntents()).andReturn(intents).anyTimes();
+
+        // These are the operations that should be done to the intentService
+        // during synchronization
+        intentService.withdraw(intent2);
+        intentService.submit(intent3);
+        intentService.submit(intent4Update);
+        intentService.submit(intent6);
+        intentService.submit(intent7);
+        EasyMock.replay(intentService);
+
+        // Start the test
+
+        // Simulate some input from the clients. The intent synchronizer has not
+        // gained the global leadership yet, but it will remember this input for
+        // when it does.
+        intentSynchronizer.submit(intent1);
+        intentSynchronizer.submit(intent2);
+        intentSynchronizer.withdraw(intent2);
+        intentSynchronizer.submit(intent3);
+        intentSynchronizer.submit(intent4);
+        intentSynchronizer.submit(intent4Update);
+        intentSynchronizer.submit(intent5);
+        intentSynchronizer.submit(intent6);
+        intentSynchronizer.submit(intent7);
+
+        // Give the leadership to the intent synchronizer. It will now attempt
+        // to synchronize the intents in the store with the intents it has
+        // recorded based on the earlier user input.
+        intentSynchronizer.modifyPrimary(true);
+
+        EasyMock.verify(intentService);
+    }
+
+    /**
+     * Tests the behavior of the submit API, both when the synchronizer has
+     * leadership and when it does not.
+     */
+    @Test
+    public void testSubmit() {
+        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+        Intent intent = intentBuilder(prefix, "00:00:00:00:00:01", SW1_ETH1);
+
+        // Set up expectations
+        intentService.submit(intent);
+        EasyMock.expect(intentService.getIntents()).andReturn(Collections.emptyList())
+                .anyTimes();
+        EasyMock.replay(intentService);
+
+        // Give the intent synchronizer leadership so it will submit intents
+        // to the intent service
+        intentSynchronizer.modifyPrimary(true);
+
+        // Test the submit
+        intentSynchronizer.submit(intent);
+
+        EasyMock.verify(intentService);
+
+        // Now we'll remove leadership from the intent synchronizer and verify
+        // that it does not submit any intents to the intent service when we
+        // call the submit API
+        EasyMock.reset(intentService);
+        EasyMock.replay(intentService);
+
+        intentSynchronizer.modifyPrimary(false);
+
+        intentSynchronizer.submit(intent);
+
+        EasyMock.verify(intentService);
+    }
+
+    /**
+     * Tests the behavior of the withdraw API, both when the synchronizer has
+     * leadership and when it does not.
+     */
+    @Test
+    public void testWithdraw() {
+        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+        Intent intent = intentBuilder(prefix, "00:00:00:00:00:01", SW1_ETH1);
+
+        // Submit an intent first so we can withdraw it later
+        intentService.submit(intent);
+        intentService.withdraw(intent);
+        EasyMock.expect(intentService.getIntents()).andReturn(Collections.emptyList())
+                .anyTimes();
+        EasyMock.replay(intentService);
+
+        // Give the intent synchronizer leadership so it will submit intents
+        // to the intent service
+        intentSynchronizer.modifyPrimary(true);
+
+        // Test the submit then withdraw
+        intentSynchronizer.submit(intent);
+        intentSynchronizer.withdraw(intent);
+
+        EasyMock.verify(intentService);
+
+        // Now we'll remove leadership from the intent synchronizer and verify
+        // that it does not withdraw any intents to the intent service when we
+        // call the withdraw API
+        EasyMock.reset(intentService);
+        EasyMock.replay(intentService);
+
+        intentSynchronizer.modifyPrimary(false);
+
+        intentSynchronizer.submit(intent);
+        intentSynchronizer.withdraw(intent);
+
+        EasyMock.verify(intentService);
+    }
+
+    /**
+     * MultiPointToSinglePointIntent builder.
+     *
+     * @param ipPrefix the ipPrefix to match
+     * @param nextHopMacAddress to which the destination MAC address in packet
+     * should be rewritten
+     * @param egressPoint to which packets should be sent
+     * @return the constructed MultiPointToSinglePointIntent
+     */
+    private MultiPointToSinglePointIntent intentBuilder(IpPrefix ipPrefix,
+            String nextHopMacAddress, ConnectPoint egressPoint) {
+
+        TrafficSelector.Builder selectorBuilder =
+                DefaultTrafficSelector.builder();
+        if (ipPrefix.isIp4()) {
+            selectorBuilder.matchEthType(Ethernet.TYPE_IPV4);
+            selectorBuilder.matchIPDst(ipPrefix);
+        } else {
+            selectorBuilder.matchEthType(Ethernet.TYPE_IPV6);
+            selectorBuilder.matchIPv6Dst(ipPrefix);
+        }
+
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MacAddress.valueOf(nextHopMacAddress));
+
+        Set<ConnectPoint> ingressPoints = new HashSet<>(connectPoints);
+        ingressPoints.remove(egressPoint);
+
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(ipPrefix.toString(), APPID))
+                        .selector(selectorBuilder.build())
+                        .treatment(treatmentBuilder.build())
+                        .ingressPoints(ingressPoints)
+                        .egressPoint(egressPoint)
+                        .build();
+        return intent;
+    }
+
+    private class TestIntentSynchronizer extends IntentSynchronizer {
+        @Override
+        protected ExecutorService createExecutor() {
+            return MoreExecutors.newDirectExecutorService();
+        }
+    }
+
+    private class TestCoreService extends CoreServiceAdapter {
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return APPID;
+        }
+    }
+
+    private class TestClusterService extends ClusterServiceAdapter {
+        @Override
+        public ControllerNode getLocalNode() {
+            return LOCAL_NODE;
+        }
+    }
+}
