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;
