diff --git a/apps/imr/app/BUCK b/apps/imr/app/BUCK
new file mode 100644
index 0000000..4f39ad8
--- /dev/null
+++ b/apps/imr/app/BUCK
@@ -0,0 +1,17 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//core/store/dist:onos-core-dist',
+    '//core/store/serializers:onos-core-serializers',
+    '//incubator/api:onos-incubator-api',
+    '//lib:KRYO',
+    '//lib:JACKSON',
+]
+
+TEST_DEPS = [
+    '//lib:TEST_ADAPTERS',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
+)
diff --git a/apps/imr/app/pom.xml b/apps/imr/app/pom.xml
new file mode 100644
index 0000000..b66ebc6
--- /dev/null
+++ b/apps/imr/app/pom.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-present Open Networking Foundation
+  ~
+  ~ 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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-apps</artifactId>
+        <version>1.13.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>onos-app-imr-app</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>Intent Monitoring and Rerouting application</description>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-misc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-incubator-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-imr-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-net</artifactId>
+            <version>1.13.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/apps/imr/app/src/main/java/org/onosproject/imr/IntentMonitorAndRerouteManager.java b/apps/imr/app/src/main/java/org/onosproject/imr/IntentMonitorAndRerouteManager.java
new file mode 100644
index 0000000..3ab49aa
--- /dev/null
+++ b/apps/imr/app/src/main/java/org/onosproject/imr/IntentMonitorAndRerouteManager.java
@@ -0,0 +1,642 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.imr;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.commons.lang3.tuple.Pair;
+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.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.imr.data.Path;
+import org.onosproject.imr.data.Route;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.ElementId;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleListener;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.ConnectivityIntent;
+import org.onosproject.net.intent.FlowRuleIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.statistic.FlowStatisticStore;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.DistributedSet;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Manager of Intent Monitor and Reroute.
+ */
+@Component(immediate = true)
+@Service
+public class IntentMonitorAndRerouteManager implements IntentMonitorAndRerouteService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private ConsistentMap<ApplicationId, Map<Key, ConnectivityIntent>> monitoredIntentsDistr;
+    private Map<ApplicationId, Map<Key, ConnectivityIntent>> monitoredIntents;
+
+    private DistributedSet<Key> toBeMonitoredIntents;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentService intentService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowStatisticStore statsStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    private InternalIntentListener intentListener = new InternalIntentListener();
+
+    private InternalFlowRuleListener flowRuleListener = new InternalFlowRuleListener();
+
+    @Activate
+    protected void activate() {
+        intentService.addListener(intentListener);
+        flowRuleService.addListener(flowRuleListener);
+
+        monitoredIntentsDistr = storageService
+                .<ApplicationId, Map<Key, ConnectivityIntent>>consistentMapBuilder()
+                .withSerializer(Serializer.using(KryoNamespaces.API))
+                .withName("IMR-monitoredIntents")
+                .build();
+        monitoredIntents = monitoredIntentsDistr.asJavaMap();
+
+        toBeMonitoredIntents = storageService.<Key>setBuilder()
+                .withSerializer(Serializer.using(
+                        new KryoNamespace.Builder()
+                                .register(KryoNamespaces.API)
+                                .register(Key.class)
+                                .build()))
+                .withName("IMR-toMonitorIntents")
+                .build()
+                .asDistributedSet();
+        log.info("IntentMonitorAndReroute activated");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        intentService.removeListener(intentListener);
+        flowRuleService.removeListener(flowRuleListener);
+        monitoredIntents
+                .forEach(((applicationId, keyConnectivityIntentMap) ->
+                        keyConnectivityIntentMap.keySet()
+                                .forEach(this::removeIntent)));
+        log.info("IntentMonitorAndReroute deactivated");
+    }
+
+
+    private synchronized void storeMonitoredIntent(ConnectivityIntent intent) {
+        log.debug("Store Monitored Intent {}", intent.key());
+        Map<Key, ConnectivityIntent> temp = monitoredIntents.getOrDefault(intent.appId(), new ConcurrentHashMap<>());
+        temp.put(intent.key(), intent);
+        monitoredIntents.put(intent.appId(), temp);
+    }
+
+    @Override
+    public synchronized boolean startMonitorIntent(Key intentKey) {
+        checkNotNull(intentKey, "Intent Key must not be null");
+        log.debug("Start Monitor Intent: {}", intentKey.toString());
+        toBeMonitoredIntents.add(intentKey);
+
+        //Check if the requested intent is already present in the intent manager
+        Intent installedIntent = intentService.getIntent(intentKey);
+        if (!allowedIntent(installedIntent)) {
+            return false;
+        }
+        //Check if the intent that is present in the intent subsystem is already installed
+        if (intentService.getIntentState(intentKey) == IntentState.INSTALLED) {
+            storeMonitoredIntent((ConnectivityIntent) installedIntent);
+        }
+        return true;
+    }
+
+
+    /**
+     * Returns whether the intent can be monitored or not.
+     * @param intent The intent you want to check if it is allowed to be monitored.
+     * @return true if the intent's type is of one of the allowed types
+     * ({@link LinkCollectionIntent}, {@link PointToPointIntent}).
+     */
+    public boolean allowedIntent(Intent intent) {
+        return intent instanceof LinkCollectionIntent || intent instanceof PointToPointIntent;
+    }
+
+    @Override
+    public synchronized boolean stopMonitorIntent(Key intentKey) {
+        checkNotNull(intentKey, "Intent key must not be null");
+        log.debug("Stop Monitor Intent: ", intentKey.toString());
+        if (!toBeMonitoredIntents.contains(intentKey)) {
+            return false;
+        }
+        removeIntent(intentKey);
+        toBeMonitoredIntents.remove(intentKey);
+        return true;
+    }
+
+    /**
+     * Removes the intent from the internal structure.
+     * @param intentKey Key of the intent to be removed.
+     * @return true if the intent is found and removed, false otherwise.
+     */
+    private synchronized boolean removeIntent(Key intentKey) {
+        for (Map.Entry<ApplicationId, Map<Key, ConnectivityIntent>> appIntents
+                : monitoredIntents.entrySet()) {
+            if (appIntents.getValue().containsKey(intentKey)) {
+                appIntents.getValue().remove(intentKey);
+                //TODO: check if it works without reputting the map
+                flushIntentStatStore(intentKey);
+                monitoredIntents.put(appIntents.getKey(), appIntents.getValue());
+                if (appIntents.getValue().isEmpty()) {
+                    monitoredIntents.remove(appIntents.getKey());
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Flushes the statistics (from the statistics store) of an intent.
+     * @param intentKey Key of the intent which statistics has to be cleaned.
+     */
+    private synchronized void flushIntentStatStore(Key intentKey) {
+        checkNotNull(intentKey);
+        //Remove all the flow rule on the stats store related to the passed intentKey
+        intentService.getInstallableIntents(intentKey)
+                .stream()
+                .map(intent -> (FlowRuleIntent) intent)
+                .forEach(intent -> intent.flowRules()
+                        .forEach(flowRule -> statsStore.removeFlowStatistic(flowRule))
+                );
+    }
+
+
+    /**
+     * Generates a new {@Link LinkCollectionIntent} applying the new path.
+     * @param links List of links of the new path.
+     * @param intentKey Key of the intent you want to re-route.
+     * @param appId Application id that submits initially the intent.
+     * @return The new intent, if not possibile it will return the old intent already installed.
+     */
+    private ConnectivityIntent generateLinkCollectionIntent(
+            List<Link> links,
+            Key intentKey,
+            ApplicationId appId) {
+        checkNotNull(links);
+        checkNotNull(appId);
+
+        // Gets the oldIntent already installed
+        ConnectivityIntent oldIntent = monitoredIntents.get(appId).get(intentKey);
+
+        //Flush the statistics of the currently installed intent
+        flushIntentStatStore(intentKey);
+
+        //get the connect point of the old intent
+        // Left element of the Pair is the ingress, right one is the egress
+        Pair<Set<FilteredConnectPoint>, Set<FilteredConnectPoint>> cpPair = extractEndConnectPoints(oldIntent);
+        if (cpPair == null) {
+            return oldIntent;
+        }
+
+        // Now generate the new intent
+        LinkCollectionIntent newIntent = LinkCollectionIntent.builder()
+                .appId(oldIntent.appId())
+                .key(intentKey)
+                .selector(oldIntent.selector())
+                .filteredIngressPoints(ImmutableSet.copyOf(cpPair.getLeft()))
+                .filteredEgressPoints(ImmutableSet.copyOf(cpPair.getRight()))
+                .treatment(oldIntent.treatment())
+                .priority(oldIntent.priority())
+                .constraints(oldIntent.constraints())
+                .links(ImmutableSet.copyOf(links))
+                //TODO: is there a way to get from the old intent?
+                .applyTreatmentOnEgress(true)
+                .build();
+
+        return newIntent;
+    }
+
+    @Override
+    public boolean applyPath(Route route) {
+        checkNotNull(route, "Route to apply must be not null");
+        checkNotNull(route.appId(), "Application id must be not null");
+        checkNotNull(route.key(), "Intent key to apply must be not null");
+        checkNotNull(route.paths(), "New path must be not null");
+        checkArgument(route.paths().size() >= 1);
+
+        ApplicationId appId = route.appId();
+        Key key = route.key();
+
+        // check if the app and the intent key are monitored
+        if (!monitoredIntents.containsKey(appId)) {
+            return false;
+        }
+        if (!monitoredIntents.get(appId).containsKey(key)) {
+            return false;
+        }
+
+        // TODO: now we manage only the unsplittable routing
+        Path currentPath = route.paths()
+                .stream()
+                .max(Path::compareTo)
+                .get();
+
+        // Check if the last and first element of the path are HostId
+        // in this case remove them from the list
+        if (currentPath.path().get(0) instanceof HostId) {
+            currentPath.path().remove(0);
+        }
+        if (currentPath.path().get(currentPath.path().size() - 1) instanceof HostId) {
+            currentPath.path().remove(currentPath.path().size() - 1);
+        }
+
+        List<Link> links = createPathFromDeviceList(currentPath.path());
+
+        // Generate the new Link collection intent, if not possible it will return the old intent
+        ConnectivityIntent intent = generateLinkCollectionIntent(links, key, appId);
+        storeMonitoredIntent(intent);
+        intentService.submit(intent);
+        return true;
+    }
+
+    @Override
+    public Map<ApplicationId, Map<Key, List<FlowEntry>>> getStats() {
+        //TODO: check if there is a better way to get the statistics
+        Map<ApplicationId, Map<Key, List<FlowEntry>>> currentStatistics = new HashMap<>();
+        monitoredIntents.forEach((appId, mapIntentKey) ->
+                                         currentStatistics.putAll(getStats(appId))
+        );
+        return currentStatistics;
+    }
+
+    @Override
+    public Map<ApplicationId, Map<Key, List<FlowEntry>>> getStats(ApplicationId appId) {
+        checkNotNull(appId);
+
+        //TODO: is there a better way to get statistics?
+        Map<ApplicationId, Map<Key, List<FlowEntry>>> currentStatistics = new HashMap<>();
+        currentStatistics.put(appId, new HashMap<>());
+        if (monitoredIntents.containsKey(appId)) {
+            Set<Key> keySet = monitoredIntents.get(appId).keySet();
+            for (Key intentKey : keySet) {
+
+                List<FlowEntry> flowEntries = getStats(intentKey);
+                currentStatistics.get(appId).put(intentKey, flowEntries);
+            }
+        }
+        return currentStatistics;
+    }
+
+    @Override
+    public Map<ApplicationId, Map<Key, List<FlowEntry>>> getStats(ApplicationId appId, Key intentKey) {
+        checkNotNull(appId);
+        checkNotNull(intentKey);
+        checkArgument(monitoredIntents.containsKey(appId));
+        checkArgument(monitoredIntents.get(appId).containsKey(intentKey));
+
+        Map<ApplicationId, Map<Key, List<FlowEntry>>> currentStatistics = new HashMap<>();
+        currentStatistics.put(appId, new HashMap<>());
+        List<FlowEntry> flowEntries = getStats(intentKey);
+        currentStatistics.get(appId).put(intentKey, flowEntries);
+        return currentStatistics;
+    }
+
+    /**
+     * Returns the list of flow entries of a particular intent.
+     * @param intentKey
+     * @return List of the flow entries of the specified intent,
+     * it contains all the statistics of that intent.
+     */
+    private List<FlowEntry> getStats(Key intentKey) {
+        List<FlowEntry> currentStatistics = new LinkedList<>();
+        intentService.getInstallableIntents(intentKey)
+                .forEach(intent -> ((FlowRuleIntent) intent).flowRules()
+                         .forEach(flowRule -> {
+                             ConnectPoint cp = buildConnectPoint(flowRule);
+                             currentStatistics.addAll(getStats(cp, flowRule));
+                         })
+                );
+        return currentStatistics;
+    }
+
+    /**
+     * Returns a list of flow entry related to the connect point and flow rule passed.
+     * @param cp ConnectPoint we want to retrieve the flow entry from.
+     * @param flowRule FlowRule.
+     * @return List of flow entries.
+     */
+    private List<FlowEntry> getStats(ConnectPoint cp, FlowRule flowRule) {
+        return statsStore.getCurrentFlowStatistic(cp)
+                .stream()
+                .filter(flowEntry -> flowEntry
+                        .id()
+                        .equals(flowRule.id()))
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * Returns a list of links starting from a list of devices.
+     * @param deviceList List of devices.
+     * @return A path in terms of list of links.
+     */
+    private List<Link> createPathFromDeviceList(List<ElementId> deviceList) {
+        List<Link> path = new ArrayList<>();
+        if (deviceList.size() == 1) {
+            return path;
+        }
+
+        // Left element represents the input and right the output
+        List<Pair<DeviceId, DeviceId>> devicePairs = IntStream.
+                range(0, deviceList.size() - 1)
+                .mapToObj(i -> Pair.of((DeviceId) deviceList.get(i), (DeviceId) deviceList.get(i + 1)))
+                .collect(Collectors.toList());
+
+        devicePairs.forEach(pair -> {
+            //TODO use GetPath pair by pair?
+            // The common Link between DevEgress and DevIngress is the intersection of their links
+            Set<Link> commonLinks = new HashSet<>(linkService.getDeviceEgressLinks(pair.getLeft()));
+            commonLinks.retainAll(linkService.getDeviceIngressLinks(pair.getRight()));
+            if (commonLinks.size() == 0) {
+                log.error("No link found between node {} and node {}!",
+                          pair.getLeft(), pair.getRight());
+            } else if (commonLinks.size() == 1) {
+                path.add(commonLinks.iterator().next());
+            } else {
+                //TODO select the one with more bandwidth?
+                log.warn("{} links found between node {} and node {}: taking the first one!",
+                         commonLinks.size(), pair.getLeft(), pair.getRight());
+                path.add(commonLinks.iterator().next());
+            }
+        });
+
+        return path;
+    }
+
+    public Map<ApplicationId, Map<Key, Pair<Set<ElementId>, Set<ElementId>>>> getMonitoredIntents() {
+        Map<ApplicationId, Map<Key, Pair<Set<ElementId>, Set<ElementId>>>> currentMonitoredIntents
+                = new ConcurrentHashMap<>();
+        monitoredIntents.forEach((appId, appIntents) -> {
+            currentMonitoredIntents.put(appId, new ConcurrentHashMap<>());
+            appIntents.forEach((intentKey, intent) -> {
+                Pair<Set<ElementId>, Set<ElementId>> endPair = extractEndPoints(intent);
+                if (endPair != null) {
+                    currentMonitoredIntents.get(appId).put(intentKey, endPair);
+                }
+            });
+        });
+        return currentMonitoredIntents;
+    }
+
+    public Map<ApplicationId, Map<Key, Pair<Set<ElementId>, Set<ElementId>>>> getMonitoredIntents(
+            ApplicationId appId) {
+        Map<ApplicationId, Map<Key, Pair<Set<ElementId>, Set<ElementId>>>> currentMonitoredIntents
+                = new ConcurrentHashMap<>();
+        currentMonitoredIntents.put(appId, new ConcurrentHashMap<>());
+        if (monitoredIntents.containsKey(appId)) {
+            monitoredIntents.get(appId).forEach((intentKey, intent) -> {
+                Pair<Set<ElementId>, Set<ElementId>> endPair = extractEndPoints(intent);
+                if (endPair != null) {
+                    currentMonitoredIntents.get(appId).put(intentKey, endPair);
+                }
+            });
+        }
+        return currentMonitoredIntents;
+    }
+
+    private Set<ElementId> connectedElements(Set<FilteredConnectPoint> cpSet) {
+        Set<ElementId> connectedElem = new HashSet<>();
+        cpSet.forEach(
+            fcp -> {
+                Set<Host> connectedHosts = hostService.getConnectedHosts(fcp.connectPoint());
+                if (connectedHosts.size() == 0) {
+                    // In this case the end point is an ELEMENT without host connected
+                    connectedElem.add(fcp.connectPoint().elementId());
+                } else {
+                    // In this case we can have a set of hosts connected to that endpoint
+                    connectedElem.addAll(connectedHosts.stream().map(Host::id)
+                                   .collect(Collectors.toSet()));
+                }
+            }
+        );
+        return connectedElem;
+    }
+
+    /**
+     * Extracts the endpoint from an intent.
+     * @param intent
+     * @return {@link Pair} containing in the Left element the set of input {@link ElementId},
+     * in the Right element the set of output {@link ElementId}.
+     */
+    private Pair<Set<ElementId>, Set<ElementId>> extractEndPoints(Intent intent) {
+        checkNotNull(intent, "intent must not be null");
+        Pair<Set<FilteredConnectPoint>, Set<FilteredConnectPoint>> cpPair;
+        cpPair = extractEndConnectPoints(intent);
+        if (cpPair == null) {
+            return null;
+        }
+        return Pair.of(connectedElements(cpPair.getLeft()), connectedElements(cpPair.getRight()));
+    }
+
+    /**
+     * Returns the end connect points of an intent.
+     * @param intent
+     * @return {@link Pair} containing in the Left element the input end connect points,
+     * in the Right element the output end connect points.
+     */
+    private Pair<Set<FilteredConnectPoint>, Set<FilteredConnectPoint>> extractEndConnectPoints(Intent intent) {
+        checkNotNull(intent, "intent must not be null");
+
+        Set<FilteredConnectPoint> inSet = new HashSet<>();
+        Set<FilteredConnectPoint> outSet = new HashSet<>();
+        if (intent instanceof PointToPointIntent) {
+            inSet.add(((PointToPointIntent) intent).filteredIngressPoint());
+            outSet.add(((PointToPointIntent) intent).filteredEgressPoint());
+        } else if (intent instanceof LinkCollectionIntent) {
+            inSet.addAll(((LinkCollectionIntent) intent).filteredIngressPoints());
+            outSet.addAll(((LinkCollectionIntent) intent).filteredEgressPoints());
+        }
+        return Pair.of(inSet, outSet);
+    }
+
+    /**
+     * Returns the connect point related to the output port of the rule.
+     * @param rule
+     * @return
+     */
+    private ConnectPoint buildConnectPoint(FlowRule rule) {
+        PortNumber port = getOutput(rule);
+
+        if (port == null) {
+            return null;
+        }
+        return new ConnectPoint(rule.deviceId(), port);
+    }
+
+    /**
+     * Returns the output port related to the rule.
+     * @param rule
+     * @return
+     */
+    private PortNumber getOutput(FlowRule rule) {
+        for (Instruction i : rule.treatment().allInstructions()) {
+            if (i.type() == Instruction.Type.OUTPUT) {
+                Instructions.OutputInstruction out = (Instructions.OutputInstruction) i;
+                return out.port();
+            }
+        }
+        return null;
+    }
+
+
+    private class InternalIntentListener implements IntentListener {
+
+        @Override
+        public void event(IntentEvent event) {
+            // It receives only events related to ConnectivityIntent to be monitored
+            Key intentKey = event.subject().key();
+            switch (event.type()) {
+                case INSTALLED:
+                    // When an intent is installed and it need to be monitored
+                    // it will pass from the "toBeMonitored" state to the "monitored" state
+                    log.info("Monitored intent INSTALLED");
+                    storeMonitoredIntent((ConnectivityIntent) event.subject());
+                    break;
+
+                case WITHDRAWN:
+                    // When an intent is withdrawn
+                    // it will go back from the "monitored" state to the "toBeMonitored"
+                    log.info("Monitored intent WITHDWRAWN");
+                    removeIntent(intentKey);
+                    break;
+
+                case FAILED:
+                    log.warn("FAILED event not handled");
+                    break;
+                default:
+                    log.warn("Unknown intent event");
+            }
+        }
+
+        @Override
+        public boolean isRelevant(IntentEvent event) {
+            /*
+             * Check if the Intent event is relevant.
+             * An intent event is relevant if it is of one of the allowed types
+             * and if it is one of the monitored ones.
+             */
+            Key intentKey = event.subject().key();
+            return allowedIntent(event.subject())
+                    && toBeMonitoredIntents.contains(intentKey);
+        }
+    }
+
+    private class InternalFlowRuleListener implements FlowRuleListener {
+        @Override
+        public void event(FlowRuleEvent event) {
+            FlowRule rule = event.subject();
+            switch (event.type()) {
+                case RULE_ADDED:
+                case RULE_UPDATED:
+                    // In case of rule update, flow statistics are updated
+                    if (rule instanceof FlowEntry) {
+                        statsStore.updateFlowStatistic((FlowEntry) rule);
+                    }
+                    break;
+                case RULE_REMOVED:
+                    // In case of rule removal, flow statistics are removed from the store
+                    log.info("Rule removed: {}", rule.id());
+                    statsStore.removeFlowStatistic(rule);
+                    break;
+                default:
+                    log.warn("Unknown flow rule event");
+            }
+        }
+
+        @Override
+        public boolean isRelevant(FlowRuleEvent event) {
+            /*
+            *  Check if the rule event is relevant and it needs to be managed
+             * A Rule event is relevant if the flow rule it refers to is
+             * part of one of the monitored intents
+             */
+            FlowRule rule = event.subject();
+            for (Map.Entry<ApplicationId, Map<Key, ConnectivityIntent>> entry : monitoredIntents.entrySet()) {
+                for (Key key : entry.getValue().keySet()) {
+                    List<Intent> ints =  intentService.getInstallableIntents(key);
+                    for (Intent i : ints) {
+                        if (i instanceof FlowRuleIntent
+                                && ((FlowRuleIntent) i).flowRules().contains(rule)) {
+                            return true;
+                        }
+                    }
+                }
+            }
+            return false;
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/imr/app/src/main/java/org/onosproject/imr/IntentMonitorAndRerouteService.java b/apps/imr/app/src/main/java/org/onosproject/imr/IntentMonitorAndRerouteService.java
new file mode 100644
index 0000000..b674149
--- /dev/null
+++ b/apps/imr/app/src/main/java/org/onosproject/imr/IntentMonitorAndRerouteService.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.imr;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.imr.data.Route;
+import org.onosproject.net.ElementId;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.intent.Key;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Intent Monitor and Reroute ONOS service.
+ */
+public interface IntentMonitorAndRerouteService {
+
+    /**
+     * Starts to monitor an intent.
+     * If the intent is not already submitted to the intent subsystem
+     * it memorizes the key and it will start to monitor it as soon as it will be installed
+     * @param intentKey Key of the intent to monitor
+     * @return true, false only if the intent is of one of the not currently supported type
+     */
+    boolean startMonitorIntent(Key intentKey);
+
+    /**
+     * Stops to monitor an intent.
+     * @param intentKey Key of the intent you want to stop the monitoring.
+     * @return false if the intent key passed is not one of the tracked intent, true otherwise.
+     */
+    boolean stopMonitorIntent(Key intentKey);
+
+    /**
+     * Applies a new route to a monitored intent.
+     * @param route Route you want to apply.
+     * @return False in case Application ID or Intent Key are not tracked by IMR
+     */
+    boolean applyPath(Route route);
+
+    /**
+     * Returns the statistics of all the monitored intents.
+     * @return Statistics (in terms of flow entries) of all the monitored intents.
+     */
+    Map<ApplicationId, Map<Key, List<FlowEntry>>> getStats();
+
+    /**
+     * Returns the statistics of all the monitored intents submitted by a specific application.
+     * @param appId Application id of the monitored intent.
+     * @return Statistics (in terms of flow entries) of the requested intents.
+     */
+    Map<ApplicationId, Map<Key, List<FlowEntry>>> getStats(ApplicationId appId);
+
+    /**
+     * Returns the statistics of a specific monitored intent.
+     * @param appId Application id of the monitored intent.
+     * @param intentKey key of the monitored intent.
+     * @return Statistics (in terms of flow entries) of the requested intent.
+     */
+    Map<ApplicationId, Map<Key, List<FlowEntry>>> getStats(ApplicationId appId, Key intentKey);
+
+    /**
+     * Returns the monitored intents in terms of key and connect points.
+     * @return Intents monitored identified by the application id and
+     * the intent key, plus the endpoints of that intent.
+     */
+    Map<ApplicationId, Map<Key, Pair<Set<ElementId>, Set<ElementId>>>> getMonitoredIntents();
+
+    /**
+     * Returns the monitored intents submitted by a specific application.
+     * @param appId Application id of the application to extract the monitored intents.
+     * @return Intents monitored identified by the application id and
+     * the intent key, plus the endpoints of that intent.
+     */
+    Map<ApplicationId, Map<Key, Pair<Set<ElementId>, Set<ElementId>>>> getMonitoredIntents(ApplicationId appId);
+}
diff --git a/apps/imr/app/src/main/java/org/onosproject/imr/data/Path.java b/apps/imr/app/src/main/java/org/onosproject/imr/data/Path.java
new file mode 100644
index 0000000..97de631
--- /dev/null
+++ b/apps/imr/app/src/main/java/org/onosproject/imr/data/Path.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.imr.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.MoreObjects;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.ElementId;
+import org.onosproject.net.HostId;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Representation of a path in terms of list of elements that it has to traverse
+ * and weight.
+ */
+public class Path implements Comparable {
+    private List<ElementId> path;
+    private float weight;
+
+    /**
+     * Returns the list of elements composing the path.
+     * @return the actual path
+     */
+    public List<ElementId> path() {
+        return path;
+    }
+
+    /**
+     * Returns the weight related to the path.
+     * @return the weight
+     */
+    public float weight() {
+        return weight;
+    }
+
+    /**
+     * Creates a Path using Jackson from a JSON Object.
+     * @param path List of element id representig the path.
+     * @param weight Weight related to the path.
+     */
+    @JsonCreator
+    public Path(@JsonProperty("path") List<String> path,
+                @JsonProperty("weight") float weight) {
+        this.path = new ArrayList<>();
+
+        path.forEach(deviceName -> {
+            try {
+                this.path.add((HostId.hostId(deviceName)));
+            } catch (IllegalArgumentException e) {
+                this.path.add(DeviceId.deviceId(deviceName));
+            }
+        });
+        this.weight = weight;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("Path", this.path())
+                .toString();
+    }
+
+    /**
+     * Compare two paths in terms of weight.
+     * @param o Object to compare
+     * @return the comparison result
+     */
+    @Override
+    public int compareTo(Object o) {
+        Path s = (Path) o;
+        if (this.weight < s.weight) {
+            return -1;
+        }
+        if (this.weight > s.weight) {
+            return 1;
+        }
+        return 0;
+    }
+}
diff --git a/apps/imr/app/src/main/java/org/onosproject/imr/data/Route.java b/apps/imr/app/src/main/java/org/onosproject/imr/data/Route.java
new file mode 100644
index 0000000..d39f2aee
--- /dev/null
+++ b/apps/imr/app/src/main/java/org/onosproject/imr/data/Route.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.imr.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.MoreObjects;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.intent.Key;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Representation of a route submitted by the off-platform application
+ * to be applied to an existing intent.
+ * It is composed by the key and the application id of the intent to modify
+ * and a list of possible {@link Path}.
+ */
+public class Route {
+    private Key key;
+    private ApplicationId appId;
+    private List<Path> paths;
+
+    /**
+     * Returns the intent key the route refers to.
+     * @return the intent key
+     */
+    public Key key() {
+        return key;
+    }
+
+    /**
+     * Returns the Application ID of the intent that has to be modified.
+     * @return the Application ID
+     */
+    public ApplicationId appId() {
+        return appId;
+    }
+
+    /**
+     * Returns the list of the {@link Path} on which the intent has to be routed.
+     * @return the list of path
+     */
+    public List<Path> paths() {
+        return paths;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("IntentKey", this.key)
+                .add("ApplicationId", this.appId)
+                .add("Paths", this.paths)
+                .toString();
+    }
+
+    /**
+     * Creates the route using Jackson from a JSON Object.
+     * @param iKey the intent key
+     * @param appId application id
+     * @param paths list of paths
+     */
+    @JsonCreator
+    public Route(@JsonProperty("key") String iKey,
+                @JsonProperty("appId") Map<String, String> appId,
+                @JsonProperty("paths") List<Path> paths) {
+        this.paths = paths;
+        this.appId = new DefaultApplicationId(Integer.valueOf(appId.get("id")), appId.get("name"));
+        this.key = Key.of(iKey, this.appId);
+    }
+}
diff --git a/apps/imr/app/src/main/java/org/onosproject/imr/data/RoutingConfigurations.java b/apps/imr/app/src/main/java/org/onosproject/imr/data/RoutingConfigurations.java
new file mode 100644
index 0000000..6d955d1
--- /dev/null
+++ b/apps/imr/app/src/main/java/org/onosproject/imr/data/RoutingConfigurations.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.imr.data;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.List;
+
+/**
+ * Representation of the routing confiuration submitted by the off-platform application
+ * It is composed by a list of {@link Route}.
+ */
+public class RoutingConfigurations {
+    public List<Route> routingList;
+
+    /**
+     * Returns the list of all the routing submitted by the off-platform application.
+     * @return the routing list
+     */
+    public List<Route> routingList() {
+        return routingList;
+    }
+
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("RoutingList", this.routingList)
+                .toString();
+    }
+
+}
diff --git a/apps/imr/app/src/main/java/org/onosproject/imr/data/package-info.java b/apps/imr/app/src/main/java/org/onosproject/imr/data/package-info.java
new file mode 100644
index 0000000..961cc1d
--- /dev/null
+++ b/apps/imr/app/src/main/java/org/onosproject/imr/data/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * Data support classes for Intent Monitor and Reroute.
+ */
+package org.onosproject.imr.data;
\ No newline at end of file
diff --git a/apps/imr/app/src/main/java/org/onosproject/imr/package-info.java b/apps/imr/app/src/main/java/org/onosproject/imr/package-info.java
new file mode 100644
index 0000000..1a5e154
--- /dev/null
+++ b/apps/imr/app/src/main/java/org/onosproject/imr/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014-present Open Networking Foundation
+ *
+ * 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 Monitor and Reroute application.
+ */
+package org.onosproject.imr;
