diff --git a/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultGroupHandler.java b/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultGroupHandler.java
index ec9e42f..80f45c6 100644
--- a/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultGroupHandler.java
+++ b/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultGroupHandler.java
@@ -152,11 +152,13 @@
      * @param newLink new neighbor link
      */
     public void linkUp(Link newLink) {
+
         if (newLink.type() != Link.Type.DIRECT) {
             log.warn("linkUp: unknown link type");
             return;
         }
 
+
         if (!newLink.src().deviceId().equals(deviceId)) {
             log.warn("linkUp: deviceId{} doesn't match with link src{}",
                      deviceId,
@@ -307,13 +309,11 @@
 
         List<Integer> nsSegmentIds = new ArrayList<Integer>();
 
-        // Add one entry for "no label" (-1) to the list if
-        // dpid list has not more than one node/neighbor as
-        // there will never be a case a packet going to more than one
-        // neighbor without a label at an edge router
-        if (neighbors.size() == 1) {
-            nsSegmentIds.add(-1);
-        }
+        // Always pair up with no edge label
+        //If (neighbors.size() == 1) {
+        nsSegmentIds.add(-1);
+        //}
+
         // Filter out SegmentIds matching with the
         // nodes in the combo
         for (Integer sId : allSegmentIds) {
@@ -405,7 +405,8 @@
         }
     }
 
-    protected GroupKey getGroupKey(Object obj) {
+    public GroupKey getGroupKey(Object obj) {
         return new DefaultGroupKey(kryo.build().serialize(obj));
     }
+
 }
diff --git a/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultGroupHandlerApp.java b/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultGroupHandlerApp.java
index bb1a035..d8183d5 100644
--- a/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultGroupHandlerApp.java
+++ b/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultGroupHandlerApp.java
@@ -90,6 +90,7 @@
     public void activate() {
         appId = coreService.registerApplication("org.onosproject.defaultgrouphandler");
         log.info("DefaultGroupHandlerApp Activating");
+
         deviceService.addListener(deviceListener);
         linkService.addListener(linkListener);
         for (Device device: deviceService.getDevices()) {
@@ -111,6 +112,7 @@
                           device.id());
             }
         }
+
         log.info("Activated");
     }
 
diff --git a/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultTransitGroupHandler.java b/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultTransitGroupHandler.java
index 1b5bb50..b820b09 100644
--- a/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultTransitGroupHandler.java
+++ b/apps/grouphandler/src/main/java/org/onosproject/grouphandler/DefaultTransitGroupHandler.java
@@ -138,7 +138,8 @@
                                             Set<DeviceId> updatedNeighbors) {
         Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(updatedNeighbors);
 
-        Set<DeviceId> tmp = updatedNeighbors;
+        Set<DeviceId> tmp = new HashSet<DeviceId>();
+        tmp.addAll(updatedNeighbors);
         tmp.remove(impactedNeighbor);
         Set<Set<DeviceId>> tmpPowerSet = getPowerSetOfNeighbors(tmp);
 
diff --git a/apps/pom.xml b/apps/pom.xml
index 93f65b5..b008f1d 100644
--- a/apps/pom.xml
+++ b/apps/pom.xml
@@ -45,6 +45,8 @@
         <module>reactive-routing</module>
         <module>bgprouter</module>
         <module>test</module>
+        <module>grouphandler</module>
+        <module>segmentrouting</module>
     </modules>
 
     <properties>
diff --git a/apps/segmentrouting/pom.xml b/apps/segmentrouting/pom.xml
new file mode 100644
index 0000000..3e541f0
--- /dev/null
+++ b/apps/segmentrouting/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2014 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">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+    <artifactId>onos-apps</artifactId>
+    <groupId>org.onosproject</groupId>
+    <version>1.2.0-SNAPSHOT</version>
+  </parent>
+
+    <artifactId>onos-app-segmentrouting</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>ONOS OSGi bundle archetype</description>
+    <url>http://onosproject.org</url>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-grouphandler</artifactId>
+            <version>1.2.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
new file mode 100644
index 0000000..5b94518
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2015 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.segmentrouting;
+
+import org.onlab.packet.ARP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.HostId;
+import org.onosproject.net.packet.OutboundPacket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class ArpHandler {
+
+    private static Logger log = LoggerFactory.getLogger(ArpHandler.class);
+
+    private SegmentRoutingManager srManager;
+    private NetworkConfigHandler config;
+
+    /**
+     * Creates an ArpHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public ArpHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.networkConfigHandler);
+    }
+
+    /**
+     * Processes incoming ARP packets.
+     * If it is an ARP request to router itself or known hosts,
+     * then it sends ARP response.
+     * If it is an ARP request to unknown hosts in its own subnet,
+     * then it flood the ARP request to the ports.
+     * If it is an ARP response, then set a flow rule for the host
+     * and forward any IP packets to the host in the packet buffer to the host.
+     *
+     * @param pkt incoming packet
+     */
+    public void processPacketIn(InboundPacket pkt) {
+
+        Ethernet ethernet = pkt.parsed();
+        ARP arp = (ARP) ethernet.getPayload();
+
+        ConnectPoint connectPoint = pkt.receivedFrom();
+        PortNumber inPort = connectPoint.port();
+        DeviceId deviceId = connectPoint.deviceId();
+        byte[] senderMacAddressByte = arp.getSenderHardwareAddress();
+        Ip4Address hostIpAddress = Ip4Address.valueOf(arp.getSenderProtocolAddress());
+
+        srManager.routingRulePopulator.populateIpRuleForHost(deviceId, hostIpAddress, MacAddress.
+                valueOf(senderMacAddressByte), inPort);
+
+        if (arp.getOpCode() == ARP.OP_REQUEST) {
+            handleArpRequest(deviceId, connectPoint, ethernet);
+        } else {
+            srManager.ipHandler.forwardPackets(deviceId, hostIpAddress);
+        }
+    }
+
+    private void handleArpRequest(DeviceId deviceId, ConnectPoint inPort, Ethernet payload) {
+
+        ARP arpRequest = (ARP) payload.getPayload();
+        HostId targetHostId = HostId.hostId(MacAddress.valueOf(
+                arpRequest.getTargetHardwareAddress()));
+
+        // ARP request for router
+        if (isArpReqForRouter(deviceId, arpRequest)) {
+            Ip4Address targetAddress = Ip4Address.valueOf(arpRequest.getTargetProtocolAddress());
+            sendArpResponse(arpRequest, config.getRouterMac(targetAddress));
+
+        // ARP request for known hosts
+        } else if (srManager.hostService.getHost(targetHostId) != null) {
+            MacAddress targetMac = srManager.hostService.getHost(targetHostId).mac();
+            sendArpResponse(arpRequest, targetMac);
+
+        // ARP request for unknown host in the subnet
+        } else if (isArpReqForSubnet(deviceId, arpRequest)) {
+            flood(payload, inPort);
+        }
+    }
+
+
+    private boolean isArpReqForRouter(DeviceId deviceId, ARP arpRequest) {
+        Ip4Address gatewayIpAddress = config.getGatewayIpAddress(deviceId);
+        if (gatewayIpAddress != null) {
+            Ip4Address targetProtocolAddress = Ip4Address.valueOf(arpRequest
+                    .getTargetProtocolAddress());
+            if (gatewayIpAddress.equals(targetProtocolAddress)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isArpReqForSubnet(DeviceId deviceId, ARP arpRequest) {
+        String subnetInfo = config.getSubnetInfo(deviceId);
+        if (subnetInfo != null) {
+            IpPrefix prefix = IpPrefix.valueOf(subnetInfo);
+            if (prefix.contains(Ip4Address.valueOf(arpRequest.getTargetProtocolAddress()))) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Sends an APR request for the target IP address to all ports except in-port.
+     *
+     * @param deviceId Switch device ID
+     * @param targetAddress target IP address for ARP
+     * @param inPort in-port
+     */
+    public void sendArpRequest(DeviceId deviceId, IpAddress targetAddress, ConnectPoint inPort) {
+
+        byte[] senderMacAddress = config.getRouterMacAddress(deviceId).toBytes();
+        byte[] senderIpAddress = config.getRouterIpAddress(deviceId)
+                .getIp4Prefix().address().toOctets();
+
+        ARP arpRequest = new ARP();
+        arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
+                  .setProtocolType(ARP.PROTO_TYPE_IP)
+                  .setHardwareAddressLength(
+                        (byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
+                  .setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH)
+                  .setOpCode(ARP.OP_REQUEST)
+                  .setSenderHardwareAddress(senderMacAddress)
+                  .setTargetHardwareAddress(MacAddress.ZERO.toBytes())
+                  .setSenderProtocolAddress(senderIpAddress)
+                  .setTargetProtocolAddress(targetAddress.toOctets());
+
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(MacAddress.BROADCAST.toBytes())
+                .setSourceMACAddress(senderMacAddress)
+                .setEtherType(Ethernet.TYPE_ARP).setPayload(arpRequest);
+
+        flood(eth, inPort);
+    }
+
+    private void sendArpResponse(ARP arpRequest, MacAddress targetMac) {
+
+        ARP arpReply = new ARP();
+        arpReply.setHardwareType(ARP.HW_TYPE_ETHERNET)
+                .setProtocolType(ARP.PROTO_TYPE_IP)
+                .setHardwareAddressLength(
+                        (byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
+                .setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH)
+                .setOpCode(ARP.OP_REPLY)
+                .setSenderHardwareAddress(targetMac.toBytes())
+                .setSenderProtocolAddress(arpRequest.getTargetProtocolAddress())
+                .setTargetHardwareAddress(arpRequest.getSenderHardwareAddress())
+                .setTargetProtocolAddress(arpRequest.getSenderProtocolAddress());
+
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress())
+                .setSourceMACAddress(targetMac.toBytes())
+                .setEtherType(Ethernet.TYPE_ARP).setPayload(arpReply);
+
+
+        HostId dstId = HostId.hostId(MacAddress.valueOf(
+                arpReply.getTargetHardwareAddress()));
+        Host dst = srManager.hostService.getHost(dstId);
+        if (dst == null) {
+            log.warn("Cannot send ARP response to unknown device");
+            return;
+        }
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().
+                setOutput(dst.location().port()).build();
+        OutboundPacket packet = new DefaultOutboundPacket(dst.location().deviceId(),
+                treatment, ByteBuffer.wrap(eth.serialize()));
+
+        srManager.packetService.emit(packet);
+    }
+
+    private void flood(Ethernet request, ConnectPoint inPort) {
+        TrafficTreatment.Builder builder;
+        ByteBuffer buf = ByteBuffer.wrap(request.serialize());
+
+        for (Port port: srManager.deviceService.getPorts(inPort.deviceId())) {
+            if (!port.number().equals(inPort.port()) &&
+                    port.number().toLong() > 0) {
+                builder = DefaultTrafficTreatment.builder();
+                builder.setOutput(port.number());
+                srManager.packetService.emit(new DefaultOutboundPacket(inPort.deviceId(),
+                        builder.build(), buf));
+            }
+        }
+    }
+
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
new file mode 100644
index 0000000..3684ec9
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2015 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.segmentrouting;
+
+import org.onlab.packet.IpPrefix;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.flow.FlowRule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class DefaultRoutingHandler {
+
+    private static Logger log = LoggerFactory.getLogger(DefaultRoutingHandler.class);
+
+    private SegmentRoutingManager srManager;
+    private RoutingRulePopulator rulePopulator;
+    private NetworkConfigHandler config;
+    private Status populationStatus;
+
+    /**
+     * Represents the default routing population status.
+     */
+    public enum Status {
+        // population process is not started yet.
+        IDLE,
+
+        // population process started.
+        STARTED,
+
+        // population process was aborted due to errors, mostly for groups not found.
+        ABORTED,
+
+        // population process was finished successfully.
+        SUCCEEDED
+    }
+
+    /**
+     * Creates a DefaultRoutingHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public DefaultRoutingHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.rulePopulator = checkNotNull(srManager.routingRulePopulator);
+        this.config = checkNotNull(srManager.networkConfigHandler);
+        this.populationStatus = Status.IDLE;
+    }
+
+    /**
+     * Populates all routing rules to all connected routers, including default
+     * routing rules, adjacency rules, and policy rules if any.
+     *
+     * @return true if it succeeds in populating all rules, otherwise false
+     */
+    public boolean populateAllRoutingRules() {
+
+        populationStatus = Status.STARTED;
+        log.info("Starts to populate routing rules");
+
+        for (Device sw : srManager.deviceService.getDevices()) {
+            if (srManager.mastershipService.
+                    getLocalRole(sw.id()) != MastershipRole.MASTER) {
+                continue;
+            }
+
+            ECMPShortestPathGraph ecmpSPG = new ECMPShortestPathGraph(sw.id(), srManager);
+            if (!populateEcmpRoutingRules(sw, ecmpSPG)) {
+                populationStatus = Status.ABORTED;
+                log.debug("Abort routing rule population");
+                return false;
+            }
+
+            // TODO: Set adjacency routing rule for all switches
+        }
+
+        populationStatus = Status.SUCCEEDED;
+        log.info("Completes routing rule population");
+        return true;
+    }
+
+    private boolean populateEcmpRoutingRules(Device sw,
+                                             ECMPShortestPathGraph ecmpSPG) {
+
+        HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia =
+                ecmpSPG.getAllLearnedSwitchesAndVia();
+        for (Integer itrIdx : switchVia.keySet()) {
+            HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap =
+                    switchVia.get(itrIdx);
+            for (DeviceId targetSw : swViaMap.keySet()) {
+                DeviceId destSw = sw.id();
+                Set<DeviceId> nextHops = new HashSet<>();
+
+                for (ArrayList<DeviceId> via : swViaMap.get(targetSw)) {
+                    if (via.isEmpty()) {
+                        nextHops.add(destSw);
+                    } else {
+                        nextHops.add(via.get(0));
+                    }
+                }
+                if (!populateEcmpRoutingRulePartial(targetSw, destSw, nextHops)) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private boolean populateEcmpRoutingRulePartial(DeviceId targetSw, DeviceId destSw,
+                                Set<DeviceId> nextHops) {
+        boolean result;
+
+        if (nextHops.isEmpty()) {
+            nextHops.add(destSw);
+        }
+
+        // If both target switch and dest switch are edge routers, then set IP rule
+        // for both subnet and router IP.
+        if (config.isEdgeRouter(targetSw) && config.isEdgeRouter(destSw)) {
+            String subnets = config.getSubnetInfo(destSw);
+            result = rulePopulator.populateIpRuleForSubnet(targetSw, subnets, destSw, nextHops);
+            if (!result) {
+                return false;
+            }
+
+            IpPrefix routerIp = config.getRouterIpAddress(destSw);
+            result = rulePopulator.populateIpRuleForRouter(targetSw, routerIp, destSw, nextHops);
+            if (!result) {
+                return false;
+            }
+
+        // If the target switch is an edge router, then set IP rules for the router IP.
+        } else if (config.isEdgeRouter(targetSw)) {
+            IpPrefix routerIp = config.getRouterIpAddress(destSw);
+            result = rulePopulator.populateIpRuleForRouter(targetSw, routerIp, destSw, nextHops);
+            if (!result) {
+                return false;
+            }
+
+        // If the target switch is an transit router, then set MPLS rules only.
+        } else if (config.isTransitRouter(targetSw)) {
+            result = rulePopulator.populateMplsRule(targetSw, destSw, nextHops);
+            if (!result) {
+                return false;
+            }
+        } else {
+            log.warn("The switch {} is neither an edge router nor a transit router.", targetSw);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Populates table miss entries for all tables, and pipeline rules for
+     * VLAN and TACM tables.
+     *
+     * @param deviceId Switch ID to set the rules
+     */
+    public void populateTtpRules(DeviceId deviceId) {
+
+        rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.VLAN,
+                true, false, false, FlowRule.Type.DEFAULT);
+        rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.ETHER,
+                true, false, false, FlowRule.Type.DEFAULT);
+        rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.IP,
+                false, true, true, FlowRule.Type.ACL);
+        rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.MPLS,
+                false, true, true, FlowRule.Type.ACL);
+        rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.ACL,
+                false, false, false, FlowRule.Type.DEFAULT);
+
+        rulePopulator.populateTableVlan(deviceId);
+        rulePopulator.populateTableTMac(deviceId);
+    }
+
+    /**
+     * Start the flow rule population process if it was never started.
+     * The process finishes successfully when all flow rules are set and
+     * stops with ABORTED status when any groups required for flows is not
+     * set yet.
+     */
+    public void startPopulationProcess() {
+        synchronized (populationStatus) {
+            if (populationStatus == Status.IDLE ||
+                    populationStatus == Status.SUCCEEDED) {
+                populationStatus = Status.STARTED;
+                populateAllRoutingRules();
+            }
+        }
+    }
+
+    /**
+     * Resume the flow rule population process if it was aborted for any reason.
+     * Mostly the process is aborted when the groups required are not set yet.
+     */
+    public void resumePopulationProcess() {
+        synchronized (populationStatus) {
+            if (populationStatus == Status.ABORTED) {
+                populationStatus = Status.STARTED;
+                // TODO: we need to restart from the point aborted instead of restarting.
+                populateAllRoutingRules();
+            }
+        }
+    }
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
new file mode 100644
index 0000000..17cfd96
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
@@ -0,0 +1,190 @@
+package org.onosproject.segmentrouting;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.grouphandler.DeviceProperties;
+import org.onosproject.net.DeviceId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class DeviceConfiguration implements DeviceProperties {
+
+    private static final Logger log = LoggerFactory
+            .getLogger(DeviceConfiguration.class);
+    private final List<Integer> allSegmentIds =
+            Arrays.asList(101, 102, 103, 104, 105, 106);
+    private HashMap<DeviceId, Integer> deviceSegmentIdMap =
+            new HashMap<DeviceId, Integer>() {
+                {
+                    put(DeviceId.deviceId("of:0000000000000001"), 101);
+                    put(DeviceId.deviceId("of:0000000000000002"), 102);
+                    put(DeviceId.deviceId("of:0000000000000003"), 103);
+                    put(DeviceId.deviceId("of:0000000000000004"), 104);
+                    put(DeviceId.deviceId("of:0000000000000005"), 105);
+                    put(DeviceId.deviceId("of:0000000000000006"), 106);
+                }
+            };
+    private final HashMap<DeviceId, MacAddress> deviceMacMap =
+            new HashMap<DeviceId, MacAddress>() {
+                {
+                    put(DeviceId.deviceId("of:0000000000000001"),
+                            MacAddress.valueOf("00:00:00:00:00:01"));
+                    put(DeviceId.deviceId("of:0000000000000002"),
+                            MacAddress.valueOf("00:00:00:00:00:02"));
+                    put(DeviceId.deviceId("of:0000000000000003"),
+                            MacAddress.valueOf("00:00:00:00:00:03"));
+                    put(DeviceId.deviceId("of:0000000000000004"),
+                            MacAddress.valueOf("00:00:00:00:00:04"));
+                    put(DeviceId.deviceId("of:0000000000000005"),
+                            MacAddress.valueOf("00:00:00:00:00:05"));
+                    put(DeviceId.deviceId("of:0000000000000006"),
+                            MacAddress.valueOf("00:00:00:00:00:06"));
+                }
+            };
+
+    private final HashMap<DeviceId, Ip4Address> deviceIpMap =
+            new HashMap<DeviceId, Ip4Address>() {
+                {
+                    put(DeviceId.deviceId("of:0000000000000001"),
+                            Ip4Address.valueOf("192.168.0.1"));
+                    put(DeviceId.deviceId("of:0000000000000002"),
+                            Ip4Address.valueOf("192.168.0.2"));
+                    put(DeviceId.deviceId("of:0000000000000003"),
+                            Ip4Address.valueOf("192.168.0.3"));
+                    put(DeviceId.deviceId("of:0000000000000004"),
+                            Ip4Address.valueOf("192.168.0.4"));
+                    put(DeviceId.deviceId("of:0000000000000005"),
+                            Ip4Address.valueOf("192.168.0.5"));
+                    put(DeviceId.deviceId("of:0000000000000006"),
+                            Ip4Address.valueOf("192.168.0.6"));
+                }
+            };
+
+    @Override
+    public int getSegmentId(DeviceId deviceId) {
+        if (deviceSegmentIdMap.get(deviceId) != null) {
+            log.debug("getSegmentId for device{} is {}",
+                    deviceId,
+                    deviceSegmentIdMap.get(deviceId));
+            return deviceSegmentIdMap.get(deviceId);
+        } else {
+            throw new IllegalStateException();
+        }
+    }
+
+
+    @Override
+    public MacAddress getDeviceMac(DeviceId deviceId) {
+        if (deviceMacMap.get(deviceId) != null) {
+            log.debug("getDeviceMac for device{} is {}",
+                    deviceId,
+                    deviceMacMap.get(deviceId));
+            return deviceMacMap.get(deviceId);
+        } else {
+            throw new IllegalStateException();
+        }
+    }
+
+
+    @Override
+    public boolean isEdgeDevice(DeviceId deviceId) {
+        if (deviceId.equals(DeviceId.deviceId("of:0000000000000001"))
+                || deviceId.equals(DeviceId.deviceId("of:0000000000000006"))) {
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public List<Integer> getAllDeviceSegmentIds() {
+        return allSegmentIds;
+    }
+
+
+    /**
+     * Returns Segment ID for the router with the MAC address given.
+     *
+     * @param targetMac Mac address for the router
+     * @return Segment ID for the router with the MAC address
+     */
+    public int getSegmentId(MacAddress targetMac) {
+        for (Map.Entry<DeviceId, MacAddress> entry: deviceMacMap.entrySet()) {
+            if (entry.getValue().equals(targetMac)) {
+                return deviceSegmentIdMap.get(entry.getKey());
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns Segment ID for the router withe IP address given.
+     *
+     * @param targetAddress IP address of the router
+     * @return Segment ID for the router with the IP address
+     */
+    public int getSegmentId(Ip4Address targetAddress) {
+        for (Map.Entry<DeviceId, Ip4Address> entry: deviceIpMap.entrySet()) {
+            if (entry.getValue().equals(targetAddress)) {
+                return deviceSegmentIdMap.get(entry.getKey());
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns Router IP address for the router with the device ID given.
+     *
+     * @param deviceId device ID of the router
+     * @return IP address of the router
+     */
+    public Ip4Address getRouterIp(DeviceId deviceId) {
+        if (deviceIpMap.get(deviceId) != null) {
+            log.debug("getDeviceIp for device{} is {}",
+                    deviceId,
+                    deviceIpMap.get(deviceId));
+            return deviceIpMap.get(deviceId);
+        } else {
+            throw new IllegalStateException();
+        }
+    }
+
+    /**
+     * Returns the Device ID of the router with the Segment ID given.
+     *
+     * @param sid Segment ID of the router
+     * @return Device ID of the router
+     */
+    public DeviceId getDeviceId(int sid) {
+        for (Map.Entry<DeviceId, Integer> entry: deviceSegmentIdMap.entrySet()) {
+            if (entry.getValue() == sid) {
+                return entry.getKey();
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the Device ID of the router with the IP address given.
+     *
+     * @param ipAddress IP address of the router
+     * @return Device ID of the router
+     */
+    public DeviceId getDeviceId(Ip4Address ipAddress) {
+        for (Map.Entry<DeviceId, Ip4Address> entry: deviceIpMap.entrySet()) {
+            if (entry.getValue().equals(ipAddress)) {
+                return entry.getKey();
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ECMPShortestPathGraph.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ECMPShortestPathGraph.java
new file mode 100644
index 0000000..cd28fcf
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ECMPShortestPathGraph.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright 2015 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.segmentrouting;
+
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DefaultPath;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This class creates bandwidth constrained breadth first tree and returns paths
+ * from root Device to leaf Devicees which satisfies the bandwidth condition. If
+ * bandwidth parameter is not specified, the normal breadth first tree will be
+ * calculated. The paths are snapshot paths at the point of the class
+ * instantiation.
+ */
+public class ECMPShortestPathGraph {
+    LinkedList<DeviceId> deviceQueue = new LinkedList<>();
+    LinkedList<Integer> distanceQueue = new LinkedList<>();
+    HashMap<DeviceId, Integer> deviceSearched = new HashMap<>();
+    HashMap<DeviceId, ArrayList<Link>> upstreamLinks = new HashMap<>();
+    HashMap<DeviceId, ArrayList<Path>> paths = new HashMap<>();
+    HashMap<Integer, ArrayList<DeviceId>> distanceDeviceMap = new HashMap<>();
+    DeviceId rootDevice;
+    private SegmentRoutingManager srManager;
+    private static final Logger log = LoggerFactory
+            .getLogger(ECMPShortestPathGraph.class);
+
+    /**
+     * Constructor.
+     *
+     * @param rootDevice root of the BFS tree
+     * @param linkListToAvoid link list to avoid
+     * @param deviceIdListToAvoid device list to avoid
+     */
+    public ECMPShortestPathGraph(DeviceId rootDevice, List<String> deviceIdListToAvoid,
+                                 List<Link> linkListToAvoid) {
+        this.rootDevice = rootDevice;
+        calcECMPShortestPathGraph(deviceIdListToAvoid, linkListToAvoid);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param rootDevice root of the BFS tree
+     * @param srManager SegmentRoutingManager object
+     */
+    public ECMPShortestPathGraph(DeviceId rootDevice, SegmentRoutingManager srManager) {
+        this.rootDevice = rootDevice;
+        this.srManager = srManager;
+        calcECMPShortestPathGraph();
+    }
+
+    /**
+     * Calculates the BFS tree using any provided constraints and Intents.
+     */
+    private void calcECMPShortestPathGraph() {
+        deviceQueue.add(rootDevice);
+        int currDistance = 0;
+        distanceQueue.add(currDistance);
+        deviceSearched.put(rootDevice, currDistance);
+        while (!deviceQueue.isEmpty()) {
+            DeviceId sw = deviceQueue.poll();
+            DeviceId prevSw = null;
+            currDistance = distanceQueue.poll();
+
+            for (Link link : srManager.linkService.getDeviceEgressLinks(sw)) {
+                DeviceId reachedDevice = link.dst().deviceId();
+                if ((prevSw != null)
+                        && (prevSw.equals(reachedDevice))) {
+                    /* Ignore LAG links between the same set of Devicees */
+                    continue;
+                } else  {
+                    prevSw = reachedDevice;
+                }
+
+                Integer distance = deviceSearched.get(reachedDevice);
+                if ((distance != null) && (distance.intValue() < (currDistance + 1))) {
+                    continue;
+                }
+                if (distance == null) {
+                    /* First time visiting this Device node */
+                    deviceQueue.add(reachedDevice);
+                    distanceQueue.add(currDistance + 1);
+                    deviceSearched.put(reachedDevice, currDistance + 1);
+
+                    ArrayList<DeviceId> distanceSwArray = distanceDeviceMap
+                            .get(currDistance + 1);
+                    if (distanceSwArray == null) {
+                        distanceSwArray = new ArrayList<DeviceId>();
+                        distanceSwArray.add(reachedDevice);
+                        distanceDeviceMap.put(currDistance + 1, distanceSwArray);
+                    } else {
+                        distanceSwArray.add(reachedDevice);
+                    }
+                }
+
+                ArrayList<Link> upstreamLinkArray =
+                        upstreamLinks.get(reachedDevice);
+                if (upstreamLinkArray == null) {
+                    upstreamLinkArray = new ArrayList<Link>();
+                    upstreamLinkArray.add(copyDefaultLink(link));
+                    //upstreamLinkArray.add(link);
+                    upstreamLinks.put(reachedDevice, upstreamLinkArray);
+                } else {
+                    /* ECMP links */
+                    upstreamLinkArray.add(copyDefaultLink(link));
+                }
+            }
+        }
+    }
+
+    /**
+     * Calculates the BFS tree using any provided constraints and Intents.
+     */
+    private void calcECMPShortestPathGraph(List<String> deviceIdListToAvoid, List<Link> linksToAvoid) {
+        deviceQueue.add(rootDevice);
+        int currDistance = 0;
+        distanceQueue.add(currDistance);
+        deviceSearched.put(rootDevice, currDistance);
+        boolean foundLinkToAvoid = false;
+        while (!deviceQueue.isEmpty()) {
+            DeviceId sw = deviceQueue.poll();
+            DeviceId prevSw = null;
+            currDistance = distanceQueue.poll();
+            for (Link link : srManager.linkService.getDeviceEgressLinks(sw)) {
+                for (Link linkToAvoid: linksToAvoid) {
+                    // TODO: equls should work
+                    //if (link.equals(linkToAvoid)) {
+                    if (linkContains(link, linksToAvoid)) {
+                        foundLinkToAvoid = true;
+                        break;
+                    }
+                }
+                if (foundLinkToAvoid) {
+                    foundLinkToAvoid = false;
+                    continue;
+                }
+                DeviceId reachedDevice = link.dst().deviceId();
+                if (deviceIdListToAvoid.contains(reachedDevice.toString())) {
+                    continue;
+                }
+                if ((prevSw != null)
+                        && (prevSw.equals(reachedDevice))) {
+                    /* Ignore LAG links between the same set of Devicees */
+                    continue;
+                } else {
+                    prevSw = reachedDevice;
+                }
+
+                Integer distance = deviceSearched.get(reachedDevice);
+                if ((distance != null) && (distance.intValue() < (currDistance + 1))) {
+                    continue;
+                }
+                if (distance == null) {
+                    /* First time visiting this Device node */
+                    deviceQueue.add(reachedDevice);
+                    distanceQueue.add(currDistance + 1);
+                    deviceSearched.put(reachedDevice, currDistance + 1);
+
+                    ArrayList<DeviceId> distanceSwArray = distanceDeviceMap
+                            .get(currDistance + 1);
+                    if (distanceSwArray == null) {
+                        distanceSwArray = new ArrayList<DeviceId>();
+                        distanceSwArray.add(reachedDevice);
+                        distanceDeviceMap.put(currDistance + 1, distanceSwArray);
+                    } else {
+                        distanceSwArray.add(reachedDevice);
+                    }
+                }
+
+                ArrayList<Link> upstreamLinkArray =
+                        upstreamLinks.get(reachedDevice);
+                if (upstreamLinkArray == null) {
+                    upstreamLinkArray = new ArrayList<Link>();
+                    upstreamLinkArray.add(copyDefaultLink(link));
+                    upstreamLinks.put(reachedDevice, upstreamLinkArray);
+                } else {
+                    /* ECMP links */
+                    upstreamLinkArray.add(copyDefaultLink(link));
+                }
+            }
+        }
+    }
+
+
+    private boolean linkContains(Link link, List<Link> links) {
+
+        DeviceId srcDevice1 = link.src().deviceId();
+        DeviceId dstDevice1 = link.dst().deviceId();
+        long srcPort1 = link.src().port().toLong();
+        long dstPort1 = link.dst().port().toLong();
+
+        for (Link link2: links) {
+            DeviceId srcDevice2 = link2.src().deviceId();
+            DeviceId dstDevice2 = link2.dst().deviceId();
+            long srcPort2 = link2.src().port().toLong();
+            long dstPort2 = link2.dst().port().toLong();
+
+            if (srcDevice1.toString().equals(srcDevice2.toString())
+                    && dstDevice1.toString().equals(dstDevice2.toString())
+                    && srcPort1 == srcPort2 && dstPort1 == dstPort2) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private void getDFSPaths(DeviceId dstDeviceDeviceId, Path path, ArrayList<Path> paths) {
+        DeviceId rootDeviceDeviceId = rootDevice;
+        for (Link upstreamLink : upstreamLinks.get(dstDeviceDeviceId)) {
+            /* Deep clone the path object */
+            Path sofarPath;
+            ArrayList<Link> sofarLinks = new ArrayList<Link>();
+            if (path != null && !path.links().isEmpty()) {
+                sofarLinks.addAll(path.links());
+            }
+            sofarLinks.add(upstreamLink);
+            sofarPath = new DefaultPath(ProviderId.NONE, sofarLinks, 0);
+            if (upstreamLink.src().deviceId().equals(rootDeviceDeviceId)) {
+                paths.add(sofarPath);
+                return;
+            } else {
+                getDFSPaths(upstreamLink.src().deviceId(), sofarPath, paths);
+            }
+        }
+    }
+
+    /**
+     * Return root Device for the graph.
+     *
+     * @return root Device
+     */
+    public DeviceId getRootDevice() {
+        return rootDevice;
+    }
+
+    /**
+     * Return the computed ECMP paths from the root Device to a given Device in
+     * the network.
+     *
+     * @param targetDevice the target Device
+     * @return the list of ECMP Paths from the root Device to the target Device
+     */
+    public ArrayList<Path> getECMPPaths(DeviceId targetDevice) {
+        ArrayList<Path> pathArray = paths.get(targetDevice);
+        if (pathArray == null && deviceSearched.containsKey(
+                targetDevice)) {
+            pathArray = new ArrayList<>();
+            DeviceId sw = targetDevice;
+            getDFSPaths(sw, null, pathArray);
+            paths.put(targetDevice, pathArray);
+        }
+        return pathArray;
+    }
+
+    /**
+     * Return the complete info of the computed ECMP paths for each Device
+     * learned in multiple iterations from the root Device.
+     *
+     * @return the hash table of Devicees learned in multiple Dijkstra
+     *         iterations and corresponding ECMP paths to it from the root
+     *         Device
+     */
+    public HashMap<Integer, HashMap<DeviceId,
+            ArrayList<Path>>> getCompleteLearnedDeviceesAndPaths() {
+
+        HashMap<Integer, HashMap<DeviceId, ArrayList<Path>>> pathGraph = new
+                HashMap<Integer, HashMap<DeviceId, ArrayList<Path>>>();
+
+        for (Integer itrIndx : distanceDeviceMap.keySet()) {
+            HashMap<DeviceId, ArrayList<Path>> swMap = new
+                    HashMap<DeviceId, ArrayList<Path>>();
+            for (DeviceId sw : distanceDeviceMap.get(itrIndx)) {
+                swMap.put(sw, getECMPPaths(sw));
+            }
+            pathGraph.put(itrIndx, swMap);
+        }
+
+        return pathGraph;
+    }
+
+    /**
+     * Return the complete info of the computed ECMP paths for each Device
+     * learned in multiple iterations from the root Device.
+     *
+     * @return the hash table of Devicees learned in multiple Dijkstra
+     *         iterations and corresponding ECMP paths in terms of Devicees to
+     *         be traversed to it from the root Device
+     */
+    public HashMap<Integer, HashMap<DeviceId,
+            ArrayList<ArrayList<DeviceId>>>> getAllLearnedSwitchesAndVia() {
+
+        HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> deviceViaMap =
+                new HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>>();
+
+        for (Integer itrIndx : distanceDeviceMap.keySet()) {
+            HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swMap =
+                    new HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>();
+
+            for (DeviceId sw : distanceDeviceMap.get(itrIndx)) {
+                ArrayList<ArrayList<DeviceId>> swViaArray = new ArrayList<>();
+                for (Path path : getECMPPaths(sw)) {
+                    ArrayList<DeviceId> swVia = new ArrayList<>();
+                    for (Link link : path.links()) {
+                        if (link.src().deviceId().equals(rootDevice)) {
+                            /* No need to add the root Device again in
+                             * the Via list
+                             */
+                            continue;
+                        }
+                        swVia.add(link.src().deviceId());
+                    }
+                    swViaArray.add(swVia);
+                }
+                swMap.put(sw, swViaArray);
+            }
+            deviceViaMap.put(itrIndx, swMap);
+        }
+        return deviceViaMap;
+    }
+
+
+    private Link copyDefaultLink(Link link) {
+        DefaultLink src = (DefaultLink) link;
+        DefaultLink defaultLink = new DefaultLink(src.providerId(), src.src(),
+                src.dst(), src.type(), src.annotations());
+
+        return defaultLink;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sBuilder = new StringBuilder();
+        for (Device device: srManager.deviceService.getDevices()) {
+            if (device.id() != rootDevice) {
+                sBuilder.append("Paths from" + rootDevice + " to " + device.id() + "\r\n");
+                ArrayList<Path> paths = getECMPPaths(device.id());
+                if (paths != null) {
+                    for (Path path : paths) {
+                        for (Link link : path.links()) {
+                            sBuilder.append(" : " + link.src() + " -> " + link.dst());
+                        }
+                    }
+                }
+            }
+        }
+        return sBuilder.toString();
+    }
+}
+
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
new file mode 100644
index 0000000..3bfb888
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2015 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.segmentrouting;
+
+import java.nio.ByteBuffer;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MPLS;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class IcmpHandler {
+
+    private static Logger log = LoggerFactory.getLogger(IcmpHandler.class);
+    private SegmentRoutingManager srManager;
+    private NetworkConfigHandler config;
+
+    /**
+     * Creates an IcmpHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public IcmpHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.networkConfigHandler);
+    }
+
+    /**
+     * Process incoming ICMP packet.
+     * If it is an ICMP request to router or known host, then sends an ICMP response.
+     * If it is an ICMP packet to known host and forward the packet to the host.
+     * If it is an ICMP packet to unknown host in a subnet, then sends an ARP request
+     * to the subnet.
+     *
+     * @param pkt
+     */
+    public void processPacketIn(InboundPacket pkt) {
+
+        Ethernet ethernet = pkt.parsed();
+        IPv4 ipv4 = (IPv4) ethernet.getPayload();
+
+        ConnectPoint connectPoint = pkt.receivedFrom();
+        DeviceId deviceId = connectPoint.deviceId();
+        Ip4Address destinationAddress =
+                Ip4Address.valueOf(ipv4.getDestinationAddress());
+        Ip4Address gatewayIpAddress = config.getGatewayIpAddress(deviceId);
+        IpPrefix routerIpPrefix = config.getRouterIpAddress(deviceId);
+        Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address();
+
+        // ICMP to the router IP or gateway IP
+        if (((ICMP) ipv4.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST &&
+                (destinationAddress.equals(routerIpAddress) ||
+                        gatewayIpAddress.equals(destinationAddress))) {
+            sendICMPResponse(ethernet, connectPoint);
+            // TODO: do we need to set the flow rule again ??
+
+        // ICMP for any known host
+        } else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
+            srManager.ipHandler.forwardPackets(deviceId, destinationAddress);
+
+        // ICMP for an unknown host in the subnet of the router
+        } else if (config.inSameSubnet(deviceId, destinationAddress)) {
+            srManager.arpHandler.sendArpRequest(deviceId, destinationAddress, connectPoint);
+
+        // ICMP for an unknown host
+        } else {
+            log.debug("ICMP request for unknown host {} ", destinationAddress);
+            // Do nothing
+        }
+    }
+
+    private void sendICMPResponse(Ethernet icmpRequest, ConnectPoint outport) {
+
+        Ethernet icmpReplyEth = new Ethernet();
+
+        IPv4 icmpRequestIpv4 = (IPv4) icmpRequest.getPayload();
+        IPv4 icmpReplyIpv4 = new IPv4();
+
+        int destAddress = icmpRequestIpv4.getDestinationAddress();
+        icmpReplyIpv4.setDestinationAddress(icmpRequestIpv4.getSourceAddress());
+        icmpReplyIpv4.setSourceAddress(destAddress);
+        icmpReplyIpv4.setTtl((byte) 64);
+        icmpReplyIpv4.setChecksum((short) 0);
+
+        ICMP icmpReply = (ICMP) icmpRequestIpv4.getPayload().clone();
+        icmpReply.setIcmpType(ICMP.TYPE_ECHO_REPLY);
+        icmpReply.setIcmpCode(ICMP.SUBTYPE_ECHO_REPLY);
+        icmpReply.setChecksum((short) 0);
+
+        icmpReplyIpv4.setPayload(icmpReply);
+
+        icmpReplyEth.setPayload(icmpReplyIpv4);
+        icmpReplyEth.setEtherType(Ethernet.TYPE_IPV4);
+        icmpReplyEth.setDestinationMACAddress(icmpRequest.getSourceMACAddress());
+        icmpReplyEth.setSourceMACAddress(icmpRequest.getDestinationMACAddress());
+        icmpReplyEth.setVlanID(icmpRequest.getVlanID());
+
+        Ip4Address destIpAddress = Ip4Address.valueOf(icmpReplyIpv4.getDestinationAddress());
+        Ip4Address destRouterAddress = config.getDestinationRouterAddress(destIpAddress);
+        int sid = config.getMplsId(destRouterAddress);
+        if (sid < 0) {
+            log.warn("Cannot find the Segment ID for {}", destAddress);
+            return;
+        }
+
+        sendPacketOut(outport, icmpReplyEth, sid);
+
+    }
+
+    private void sendPacketOut(ConnectPoint outport, Ethernet payload, int sid) {
+
+        IPv4 ipPacket = (IPv4) payload.getPayload();
+        Ip4Address destIpAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress());
+
+        if (sid == -1 || config.getMplsId(payload.getDestinationMAC()) == sid ||
+                config.inSameSubnet(outport.deviceId(), destIpAddress)) {
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().
+                    setOutput(outport.port()).build();
+            OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(),
+                    treatment, ByteBuffer.wrap(payload.serialize()));
+            srManager.packetService.emit(packet);
+        } else {
+            log.warn("Send a MPLS packet as a ICMP response");
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(outport.port())
+                    .build();
+
+            payload.setEtherType(Ethernet.MPLS_UNICAST);
+            MPLS mplsPkt = new MPLS();
+            mplsPkt.setLabel(sid);
+            mplsPkt.setTtl(((IPv4) payload.getPayload()).getTtl());
+            mplsPkt.setPayload(payload.getPayload());
+            payload.setPayload(mplsPkt);
+
+            OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(),
+                    treatment, ByteBuffer.wrap(payload.serialize()));
+
+            srManager.packetService.emit(packet);
+        }
+    }
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java
new file mode 100644
index 0000000..cca8692
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2015 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.segmentrouting;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class IpHandler {
+
+    private static Logger log = LoggerFactory.getLogger(IpHandler.class);
+    private SegmentRoutingManager srManager;
+    private NetworkConfigHandler config;
+    private ConcurrentHashMap<Ip4Address, ConcurrentLinkedQueue<IPv4>> ipPacketQueue;
+
+    /**
+     * Creates an IpHandler object.
+     *
+     * @param srManager SegmentRoutingManager object
+     */
+    public IpHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.networkConfigHandler);
+        ipPacketQueue = new ConcurrentHashMap<Ip4Address, ConcurrentLinkedQueue<IPv4>>();
+    }
+
+    /**
+     * Processes incoming IP packets.
+     *
+     * If it is an IP packet for known host, then forward it to the host.
+     * If it is an IP packet for unknown host in subnet, then send an ARP request
+     * to the subnet.
+     *
+     * @param pkt incoming packet
+     */
+    public void processPacketIn(InboundPacket pkt) {
+        Ethernet ethernet = pkt.parsed();
+        IPv4 ipv4 = (IPv4) ethernet.getPayload();
+
+        ConnectPoint connectPoint = pkt.receivedFrom();
+        DeviceId deviceId = connectPoint.deviceId();
+        Ip4Address destinationAddress =
+                Ip4Address.valueOf(ipv4.getDestinationAddress());
+
+        // IP packet for know hosts
+        if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
+            forwardPackets(deviceId, destinationAddress);
+
+        // IP packet for unknown host in the subnet of the router
+        } else if (config.inSameSubnet(deviceId, destinationAddress)) {
+            srManager.arpHandler.sendArpRequest(deviceId, destinationAddress, connectPoint);
+
+        // IP packets for unknown host
+        } else {
+            log.debug("ICMP request for unknown host {} which is not in the subnet",
+                    destinationAddress);
+            // Do nothing
+        }
+    }
+
+    /**
+     * Adds the IP packet to a buffer.
+     * The packets are forwarded to corresponding destination when the destination
+     * MAC address is known via ARP response.
+     *
+     * @param ipPacket IP packet to add to the buffer
+     */
+    public void addToPacketBuffer(IPv4 ipPacket) {
+
+        // Better not buffer TPC packets due to out-of-order packet transfer
+        if (ipPacket.getProtocol() == IPv4.PROTOCOL_TCP) {
+            return;
+        }
+
+        Ip4Address destIpAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress());
+
+        if (ipPacketQueue.get(destIpAddress) == null) {
+            ConcurrentLinkedQueue<IPv4> queue = new ConcurrentLinkedQueue<IPv4>();
+            queue.add(ipPacket);
+            ipPacketQueue.put(destIpAddress, queue);
+        } else {
+            ipPacketQueue.get(destIpAddress).add(ipPacket);
+        }
+    }
+
+    /**
+     * Forwards IP packets in the buffer to the destination IP address.
+     * It is called when the controller finds the destination MAC address
+     * via ARP responsees.
+     *
+     * @param deviceId switch device ID
+     * @param destIpAddress destination IP address
+     */
+    public void forwardPackets(DeviceId deviceId, Ip4Address destIpAddress) {
+        for (IPv4 ipPacket : ipPacketQueue.get(destIpAddress)) {
+            Ip4Address destAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress());
+            if (ipPacket != null && config.inSameSubnet(deviceId, destAddress)) {
+                ipPacket.setTtl((byte) (ipPacket.getTtl() - 1));
+                ipPacket.setChecksum((short) 0);
+                for (Host dest: srManager.hostService.getHostsByIp(destIpAddress)) {
+                    Ethernet eth = new Ethernet();
+                    eth.setDestinationMACAddress(dest.mac());
+                    eth.setSourceMACAddress(config.getRouterMacAddress(
+                            deviceId));
+                    eth.setEtherType(Ethernet.TYPE_IPV4);
+                    eth.setPayload(ipPacket);
+
+                    TrafficTreatment treatment = DefaultTrafficTreatment.builder().
+                            setOutput(dest.location().port()).build();
+                    OutboundPacket packet = new DefaultOutboundPacket(deviceId,
+                            treatment, ByteBuffer.wrap(eth.serialize()));
+                    srManager.packetService.emit(packet);
+                }
+            }
+        }
+    }
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/NetworkConfigHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/NetworkConfigHandler.java
new file mode 100644
index 0000000..2cb5867
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/NetworkConfigHandler.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2015 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.segmentrouting;
+
+import com.google.common.collect.Lists;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is temporary class and used only for test.
+ * It will be replaced with "real" Network Config Manager.
+ */
+
+public class NetworkConfigHandler {
+
+    private static Logger log = LoggerFactory.getLogger(NetworkConfigHandler.class);
+    private SegmentRoutingManager srManager;
+    private DeviceConfiguration deviceConfig = new DeviceConfiguration();
+
+    public NetworkConfigHandler(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+    }
+
+    public Ip4Address getGatewayIpAddress(DeviceId deviceId) {
+
+        if (deviceId.uri().equals(URI.create("of:0000000000000001"))) {
+            return Ip4Address.valueOf("10.0.1.128");
+        } else if (deviceId.uri().equals(URI.create("of:0000000000000006"))) {
+            return Ip4Address.valueOf("7.7.7.128");
+        }
+
+        log.warn("No gateway Ip address was found for {}", deviceId);
+        return Ip4Address.valueOf("0.0.0.0");
+    }
+
+    public IpPrefix getRouterIpAddress(DeviceId deviceId) {
+
+        return IpPrefix.valueOf(deviceConfig.getRouterIp(deviceId), 32);
+    }
+
+    public MacAddress getRouterMacAddress(DeviceId deviceId) {
+        return deviceConfig.getDeviceMac(deviceId);
+    }
+
+    public boolean inSameSubnet(DeviceId deviceId, Ip4Address destIp) {
+
+        String subnetInfo = getSubnetInfo(deviceId);
+        if (subnetInfo == null) {
+            return false;
+        }
+
+        IpPrefix prefix = IpPrefix.valueOf(subnetInfo);
+        if (prefix.contains(destIp)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean inSameSubnet(Ip4Address address, int sid) {
+        DeviceId deviceId = deviceConfig.getDeviceId(sid);
+        if (deviceId == null) {
+            log.warn("Cannot find a device for SID {}", sid);
+            return false;
+        }
+
+        String subnetInfo = getSubnetInfo(deviceId);
+        if (subnetInfo == null) {
+            log.warn("Cannot find the subnet info for {}", deviceId);
+            return false;
+        }
+
+        Ip4Prefix subnet = Ip4Prefix.valueOf(subnetInfo);
+        if (subnet.contains(address)) {
+            return true;
+        }
+
+        return false;
+
+    }
+
+    public String getSubnetInfo(DeviceId deviceId) {
+        // TODO : supports multiple subnet
+        if (deviceId.uri().equals(URI.create("of:0000000000000001"))) {
+            return "10.0.1.1/24";
+        } else if (deviceId.uri().equals(URI.create("of:0000000000000006"))) {
+            return "7.7.7.7/24";
+        } else {
+            log.error("Switch {} is not an edge router", deviceId);
+            return null;
+        }
+    }
+
+    public int getMplsId(DeviceId deviceId) {
+        return deviceConfig.getSegmentId(deviceId);
+    }
+
+    public int getMplsId(MacAddress mac) {
+        return deviceConfig.getSegmentId(mac);
+    }
+
+    public int getMplsId(Ip4Address address) {
+        return deviceConfig.getSegmentId(address);
+    }
+
+    public boolean isEcmpNotSupportedInTransit(DeviceId deviceId) {
+        return false;
+    }
+
+    public boolean isTransitRouter(DeviceId deviceId) {
+        return true;
+    }
+
+
+    public boolean isEdgeRouter(DeviceId deviceId) {
+        if (deviceId.uri().equals(URI.create("of:0000000000000001"))
+                || deviceId.uri().equals(URI.create("of:0000000000000006"))) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private List<PortNumber> getPortsToNeighbors(DeviceId deviceId, List<DeviceId> fwdSws) {
+
+        List<PortNumber> portNumbers = Lists.newArrayList();
+
+        Set<Link> links = srManager.linkService.getDeviceEgressLinks(deviceId);
+        for (Link link: links) {
+            for (DeviceId swId: fwdSws) {
+                if (link.dst().deviceId().equals(swId)) {
+                    portNumbers.add(link.src().port());
+                    break;
+                }
+            }
+        }
+
+        return portNumbers;
+    }
+
+    public List<PortNumber> getPortsToDevice(DeviceId deviceId) {
+        List<PortNumber> portNumbers = Lists.newArrayList();
+
+        Set<Link> links = srManager.linkService.getDeviceEgressLinks(deviceId);
+        for (Link link: links) {
+            if (link.dst().deviceId().equals(deviceId)) {
+                portNumbers.add(link.src().port());
+            }
+        }
+
+        return portNumbers;
+    }
+
+
+    public Ip4Address getDestinationRouterAddress(Ip4Address destIpAddress) {
+        // TODO: need to check the subnet info
+        if (destIpAddress.toString().equals("10.0.1.1")) {
+            return Ip4Address.valueOf("192.168.0.1");
+        } else if (destIpAddress.toString().equals("7.7.7.7")) {
+            return Ip4Address.valueOf("192.168.0.6");
+        } else {
+            log.warn("No router was found for {}", destIpAddress);
+            return null;
+        }
+
+    }
+
+    public DeviceId getDeviceId(Ip4Address ip4Address) {
+        return deviceConfig.getDeviceId(ip4Address);
+    }
+
+    public MacAddress getRouterMac(Ip4Address targetAddress) {
+        if (targetAddress.toString().equals("10.0.1.128")) {
+            return MacAddress.valueOf("00:00:00:00:00:01");
+        } else if (targetAddress.toString().equals("7.7.7.128")) {
+            return MacAddress.valueOf("00:00:00:00:00:06");
+        } else {
+            log.warn("Cannot find a router for {}", targetAddress);
+            return null;
+        }
+    }
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
new file mode 100644
index 0000000..063517e
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright 2015 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.segmentrouting;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+
+import org.onlab.packet.MplsLabel;
+import org.onosproject.grouphandler.NeighborSet;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class RoutingRulePopulator {
+
+    private static final Logger log = LoggerFactory.getLogger(RoutingRulePopulator.class);
+
+    private SegmentRoutingManager srManager;
+    private NetworkConfigHandler config;
+
+    /**
+     * Creates a RoutingRulePopulator object.
+     *
+     * @param srManager
+     */
+    public RoutingRulePopulator(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.networkConfigHandler);
+    }
+
+    /**
+     * Populates IP flow rules for specific hosts directly connected to the switch.
+     *
+     * @param deviceId switch ID to set the rules
+     * @param hostIp host IP address
+     * @param hostMac host MAC address
+     * @param outPort port where the host is connected
+     */
+    public void populateIpRuleForHost(DeviceId deviceId, Ip4Address hostIp,
+                                      MacAddress hostMac, PortNumber outPort) {
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, 32));
+        sbuilder.matchEthType(Ethernet.TYPE_IPV4);
+
+        tbuilder.setEthDst(hostMac)
+                .setEthSrc(config.getRouterMacAddress(deviceId))
+                .setOutput(outPort);
+
+        TrafficTreatment treatment = tbuilder.build();
+        TrafficSelector selector = sbuilder.build();
+
+        FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                srManager.appId, 600, false, FlowRule.Type.IP);
+
+        srManager.flowRuleService.applyFlowRules(f);
+        log.debug("Flow rule {} is set to switch {}", f, deviceId);
+    }
+
+    /**
+     * Populates IP flow rules for the subnets of the destination router.
+     *
+     * @param deviceId switch ID to set the rules
+     * @param subnetInfo subnet information
+     * @param destSw destination switch ID
+     * @param nextHops next hop switch ID list
+     * @return true if all rules are set successfully, false otherwise
+     */
+    public boolean populateIpRuleForSubnet(DeviceId deviceId, String subnetInfo,
+                                           DeviceId destSw, Set<DeviceId> nextHops) {
+
+        List<IpPrefix> subnets = extractSubnet(subnetInfo);
+        for (IpPrefix subnet: subnets) {
+            if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Populates IP flow rules for the router IP address.
+     *
+     * @param deviceId device ID to set the rules
+     * @param ipPrefix the IP address of the destination router
+     * @param destSw device ID of the destination router
+     * @param nextHops next hop switch ID list
+     * @return true if all rules are set successfully, false otherwise
+     */
+    public boolean populateIpRuleForRouter(DeviceId deviceId, IpPrefix ipPrefix,
+                                           DeviceId destSw, Set<DeviceId> nextHops) {
+
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        sbuilder.matchIPDst(ipPrefix);
+        sbuilder.matchEthType(Ethernet.TYPE_IPV4);
+
+        NeighborSet ns = null;
+
+        //If the next hop is the same as the final destination, then MPLS label is not set.
+        if (nextHops.size() == 1 && nextHops.toArray()[0].equals(destSw)) {
+            tbuilder.decNwTtl();
+            ns = new NeighborSet(nextHops);
+        } else {
+            tbuilder.copyTtlOut();
+            ns = new NeighborSet(nextHops, config.getMplsId(destSw));
+        }
+
+        DefaultGroupKey groupKey = (DefaultGroupKey) srManager.getGroupKey(ns);
+        if (groupKey == null) {
+            log.warn("Group key is not found for ns {}", ns);
+            return false;
+        }
+        Group group = srManager.groupService.getGroup(deviceId, groupKey);
+        if (group != null) {
+            tbuilder.group(group.id());
+        } else {
+            log.warn("No group found for NeighborSet {} from {} to {}",
+                    ns, deviceId, destSw);
+            return false;
+        }
+
+        TrafficTreatment treatment = tbuilder.build();
+        TrafficSelector selector = sbuilder.build();
+
+        FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                srManager.appId, 600, false, FlowRule.Type.IP);
+
+        srManager.flowRuleService.applyFlowRules(f);
+        log.debug("IP flow rule {} is set to switch {}", f, deviceId);
+
+        return true;
+    }
+
+
+    /**
+     * Populates MPLS flow rules to all transit routers.
+     *
+     * @param deviceId device ID of the switch to set the rules
+     * @param destSwId destination switch device ID
+     * @param nextHops next hops switch ID list
+     * @return true if all rules are set successfully, false otherwise
+     */
+    public boolean populateMplsRule(DeviceId deviceId, DeviceId destSwId, Set<DeviceId> nextHops) {
+
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        Collection<TrafficTreatment> treatments = new ArrayList<>();
+
+        // TODO Handle the case of Bos == false
+        sbuilder.matchMplsLabel(MplsLabel.mplsLabel(config.getMplsId(destSwId)));
+        sbuilder.matchEthType(Ethernet.MPLS_UNICAST);
+
+        //If the next hop is the destination router, do PHP
+        if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
+            TrafficTreatment treatmentBos =
+                    getMplsTreatment(deviceId, destSwId, nextHops, true, true);
+            TrafficTreatment treatment =
+                    getMplsTreatment(deviceId, destSwId, nextHops, true, false);
+            if (treatmentBos != null) {
+                treatments.add(treatmentBos);
+            } else {
+                log.warn("Failed to set MPLS rules.");
+                return false;
+            }
+        } else {
+            TrafficTreatment treatmentBos =
+                    getMplsTreatment(deviceId, destSwId, nextHops, false, true);
+            TrafficTreatment treatment =
+                    getMplsTreatment(deviceId, destSwId, nextHops, false, false);
+
+            if (treatmentBos != null) {
+                treatments.add(treatmentBos);
+            } else {
+                log.warn("Failed to set MPLS rules.");
+                return false;
+            }
+        }
+
+        TrafficSelector selector = sbuilder.build();
+        for (TrafficTreatment treatment: treatments) {
+            FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                    srManager.appId, 600, false, FlowRule.Type.MPLS);
+            srManager.flowRuleService.applyFlowRules(f);
+            log.debug("MPLS rule {} is set to {}", f, deviceId);
+        }
+
+        return true;
+    }
+
+
+    private TrafficTreatment getMplsTreatment(DeviceId deviceId, DeviceId destSw,
+                                             Set<DeviceId> nextHops,
+                                             boolean phpRequired, boolean isBos) {
+
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        if (phpRequired) {
+            tbuilder.copyTtlIn();
+            if (isBos) {
+                tbuilder.popMpls(Ethernet.TYPE_IPV4)
+                        .decNwTtl();
+            } else {
+                tbuilder.popMpls(Ethernet.MPLS_UNICAST)
+                .decMplsTtl();
+            }
+        } else {
+            tbuilder.decMplsTtl();
+        }
+
+        if (config.isEcmpNotSupportedInTransit(deviceId)
+                && config.isTransitRouter(deviceId)) {
+            Link link = selectOneLink(deviceId, nextHops);
+            if (link == null) {
+                log.warn("No link from {} to {}", deviceId, nextHops);
+                return null;
+            }
+            tbuilder.setEthSrc(config.getRouterMacAddress(deviceId))
+                    .setEthDst(config.getRouterMacAddress(link.dst().deviceId()))
+                    .setOutput(link.src().port());
+        } else {
+            NeighborSet ns = new NeighborSet(nextHops);
+            DefaultGroupKey groupKey = (DefaultGroupKey) srManager.getGroupKey(ns);
+            if (groupKey == null) {
+                log.warn("Group key is not found for ns {}", ns);
+                return null;
+            }
+            Group group = srManager.groupService.getGroup(deviceId, groupKey);
+            if (group != null) {
+                tbuilder.group(group.id());
+            } else {
+                log.warn("No group found for ns {} key {} in {}", ns,
+                        srManager.getGroupKey(ns), deviceId);
+                return null;
+            }
+        }
+
+        return tbuilder.build();
+    }
+
+    /**
+     * Populates VLAN flows rules.
+     * All packets are forwarded to TMAC table.
+     *
+     * @param deviceId switch ID to set the rules
+     */
+    public void populateTableVlan(DeviceId deviceId) {
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        tbuilder.transition(FlowRule.Type.ETHER);
+
+        TrafficTreatment treatment = tbuilder.build();
+        TrafficSelector selector = sbuilder.build();
+
+        FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                srManager.appId, 600, false, FlowRule.Type.VLAN);
+
+        srManager.flowRuleService.applyFlowRules(f);
+
+        log.debug("Vlan flow rule {} is set to switch {}", f, deviceId);
+    }
+
+    /**
+     * Populates TMAC table rules.
+     * IP packets are forwarded to IP table.
+     * MPLS packets are forwarded to MPLS table.
+     *
+     * @param deviceId switch ID to set the rules
+     */
+    public void populateTableTMac(DeviceId deviceId) {
+
+        // flow rule for IP packets
+        TrafficSelector selectorIp = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchEthDst(config.getRouterMacAddress(deviceId))
+                .build();
+        TrafficTreatment treatmentIp = DefaultTrafficTreatment.builder()
+                .transition(FlowRule.Type.IP)
+                .build();
+
+        FlowRule flowIp = new DefaultFlowRule(deviceId, selectorIp, treatmentIp, 100,
+                srManager.appId, 600, false, FlowRule.Type.ETHER);
+
+        srManager.flowRuleService.applyFlowRules(flowIp);
+
+        // flow rule for MPLS packets
+        TrafficSelector selectorMpls = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.MPLS_UNICAST)
+                .matchEthDst(config.getRouterMacAddress(deviceId))
+                .build();
+        TrafficTreatment treatmentMpls = DefaultTrafficTreatment.builder()
+                .transition(FlowRule.Type.MPLS)
+                .build();
+
+        FlowRule flowMpls = new DefaultFlowRule(deviceId, selectorMpls, treatmentMpls, 100,
+                srManager.appId, 600, false, FlowRule.Type.ETHER);
+
+        srManager.flowRuleService.applyFlowRules(flowMpls);
+
+    }
+
+    /**
+     * Populates a table miss entry.
+     *
+     * @param deviceId switch ID to set rules
+     * @param tableToAdd table to set the rules
+     * @param toControllerNow flag to send packets to controller immediately
+     * @param toControllerWrite flag to send packets to controller at the end of pipeline
+     * @param toTable flag to send packets to a specific table
+     * @param tableToSend table type to send packets when the toTable flag is set
+     */
+    public void populateTableMissEntry(DeviceId deviceId, FlowRule.Type tableToAdd, boolean toControllerNow,
+                                       boolean toControllerWrite,
+                                       boolean toTable, FlowRule.Type tableToSend) {
+        // TODO: Change arguments to EnumSet
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .build();
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+        if (toControllerNow) {
+            tBuilder.setOutput(PortNumber.CONTROLLER);
+        }
+
+        if (toControllerWrite) {
+            tBuilder.deferred().setOutput(PortNumber.CONTROLLER);
+        }
+
+        if (toTable) {
+            tBuilder.transition(tableToSend);
+        }
+
+        FlowRule flow = new DefaultFlowRule(deviceId, selector, tBuilder.build(), 0,
+                srManager.appId, 600, false, tableToAdd);
+
+        srManager.flowRuleService.applyFlowRules(flow);
+
+    }
+
+
+    private List<IpPrefix> extractSubnet(String subnetInfo) {
+        List<IpPrefix> subnetIpPrefixes = new ArrayList<>();
+
+        // TODO: refactoring required depending on the format of the subnet info
+        IpPrefix prefix = IpPrefix.valueOf(subnetInfo);
+        if (prefix == null) {
+            log.error("Wrong ip prefix type {}", subnetInfo);
+        } else {
+            subnetIpPrefixes.add(prefix);
+        }
+
+        return subnetIpPrefixes;
+    }
+
+    private Link selectOneLink(DeviceId srcId, Set<DeviceId> destIds) {
+
+        Set<Link> links = srManager.linkService.getDeviceEgressLinks(srcId);
+        DeviceId destId = (DeviceId) destIds.toArray()[0];
+        for (Link link: links) {
+            if (link.dst().deviceId().equals(destId)) {
+                return link;
+            }
+        }
+
+        return null;
+    }
+
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
new file mode 100644
index 0000000..a7a3b11
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2015 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.segmentrouting;
+
+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.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.Event;
+import org.onosproject.grouphandler.DefaultGroupHandler;
+import org.onosproject.grouphandler.NeighborSet;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.Port;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupEvent;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupListener;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.topology.TopologyService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+@SuppressWarnings("ALL")
+@Component(immediate = true)
+public class SegmentRoutingManager {
+
+    private static Logger log = LoggerFactory.getLogger(SegmentRoutingManager.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TopologyService topologyService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentService intentService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected GroupService groupService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    protected NetworkConfigHandler networkConfigHandler = new NetworkConfigHandler(this);
+    protected ArpHandler arpHandler = new ArpHandler(this);
+    protected IcmpHandler icmpHandler = new IcmpHandler(this);
+    protected IpHandler ipHandler = new IpHandler(this);
+    protected RoutingRulePopulator routingRulePopulator = new RoutingRulePopulator(this);
+    protected ApplicationId appId;
+
+    private DefaultRoutingHandler defaultRoutingHandler = new DefaultRoutingHandler(this);
+    private DeviceConfiguration deviceConfiguration = new DeviceConfiguration();
+    private InternalPacketProcessor processor = new InternalPacketProcessor();
+    private InternalEventHandler eventHandler = new InternalEventHandler();
+
+    private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
+
+    private static ScheduledFuture<?> eventHandlerFuture = null;
+    private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>();
+    private Map<DeviceId, DefaultGroupHandler> groupHandlerMap
+            = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>();
+
+    private static int numOfEvents = 0;
+    private static int numOfHandlerExecution = 0;
+    private static int numOfHandlerScheduled = 0;
+
+    @Activate
+    protected void activate() {
+        appId = coreService.registerApplication("org.onosproject.segmentrouting");
+        packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
+        linkService.addListener(new InternalLinkListener());
+        groupService.addListener(new InternalGroupListener());
+        deviceService.addListener(new InternalDeviceListener());
+
+        for (Device device: deviceService.getDevices()) {
+            if (mastershipService.
+                    getLocalRole(device.id()) == MastershipRole.MASTER) {
+                DefaultGroupHandler groupHandler =
+                    DefaultGroupHandler.createGroupHandler(device.id(),
+                            appId, deviceConfiguration, linkService, groupService);
+                groupHandler.createGroups();
+                groupHandlerMap.put(device.id(), groupHandler);
+                log.debug("Initiating default group handling for {}", device.id());
+
+                defaultRoutingHandler.startPopulationProcess();
+            } else {
+                log.debug("Activate: Local role {} "
+                                + "is not MASTER for device {}",
+                        mastershipService.
+                                getLocalRole(device.id()),
+                        device.id());
+            }
+        }
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        packetService.removeProcessor(processor);
+        processor = null;
+        log.info("Stopped");
+    }
+
+    /**
+     * Returns the GrouopKey object for the device and the NighborSet given.
+     *
+     * @param ns NeightborSet object for the GroupKey
+     * @return GroupKey object for the NeighborSet
+     */
+    public GroupKey getGroupKey(NeighborSet ns) {
+
+        for (DefaultGroupHandler groupHandler: groupHandlerMap.values()) {
+            return groupHandler.getGroupKey(ns);
+        }
+
+        return null;
+    }
+
+    private class InternalPacketProcessor implements PacketProcessor {
+
+        @Override
+        public void process(PacketContext context) {
+
+            if (context.isHandled()) {
+                return;
+            }
+
+            InboundPacket pkt = context.inPacket();
+            Ethernet ethernet = pkt.parsed();
+
+            if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
+                arpHandler.processPacketIn(pkt);
+            } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
+                IPv4 ipPacket = (IPv4) ethernet.getPayload();
+                ipHandler.addToPacketBuffer(ipPacket);
+                if (ipPacket.getProtocol() == IPv4.PROTOCOL_ICMP) {
+                    icmpHandler.processPacketIn(pkt);
+                } else {
+                    ipHandler.processPacketIn(pkt);
+                }
+            }
+        }
+    }
+
+    private class InternalLinkListener implements LinkListener {
+        @Override
+        public void event(LinkEvent event) {
+            if (event.type() == LinkEvent.Type.LINK_ADDED ||
+                    event.type() == LinkEvent.Type.LINK_REMOVED) {
+                scheduleEventHandlerIfNotScheduled(event);
+            }
+        }
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+
+        @Override
+        public void event(DeviceEvent event) {
+            if (mastershipService.
+                    getLocalRole(event.subject().id()) != MastershipRole.MASTER) {
+                log.debug("Local role {} is not MASTER for device {}",
+                        mastershipService.
+                                getLocalRole(event.subject().id()),
+                        event.subject().id());
+                return;
+            }
+
+            switch (event.type()) {
+            case DEVICE_ADDED:
+            case PORT_REMOVED:
+                scheduleEventHandlerIfNotScheduled(event);
+                break;
+            default:
+            }
+        }
+    }
+
+    private class InternalGroupListener implements GroupListener {
+
+        @Override
+        public void event(GroupEvent event) {
+            switch (event.type()) {
+                case GROUP_ADDED:
+                    scheduleEventHandlerIfNotScheduled(event);
+                    break;
+                case GROUP_ADD_REQUESTED:
+                    log.info("Group add requested");
+                    break;
+                case GROUP_UPDATED:
+                    break;
+                default:
+                    log.warn("Unhandled group event type: {}", event.type());
+            }
+        }
+    }
+
+    private void scheduleEventHandlerIfNotScheduled(Event event) {
+
+        eventQueue.add(event);
+        numOfEvents++;
+        if (eventHandlerFuture == null ||
+                eventHandlerFuture.isDone()) {
+            eventHandlerFuture = executorService.schedule(eventHandler,
+                    100, TimeUnit.MILLISECONDS);
+            numOfHandlerScheduled++;
+        }
+
+        log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents,
+                numOfHandlerScheduled);
+
+    }
+
+    private class InternalEventHandler implements Runnable {
+
+        public void run() {
+            numOfHandlerExecution++;
+            while (!eventQueue.isEmpty()) {
+                Event event = eventQueue.poll();
+                if (event.type() == LinkEvent.Type.LINK_ADDED) {
+                    processLinkAdded((Link) event.subject());
+                } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
+                    processLinkRemoved((Link) event.subject());
+                } else if (event.type() == GroupEvent.Type.GROUP_ADDED) {
+                    processGroupAdded((Group) event.subject());
+                } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED) {
+                    processDeviceAdded((Device) event.subject());
+                } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
+                    processPortRemoved((Device) event.subject(),
+                            ((DeviceEvent) event).port());
+                } else {
+                    log.warn("Unhandled event type: {}", event.type());
+                }
+            }
+            log.debug("numOfHandlerExecution {} numOfEventHanlderScheduled {} numOfEvents {}",
+                    numOfHandlerExecution, numOfHandlerScheduled, numOfEvents);
+        }
+    }
+
+
+
+    private void processLinkAdded(Link link) {
+        log.debug("A new link {} was added", link.toString());
+
+        if (mastershipService.
+                getLocalRole(link.src().deviceId()) == MastershipRole.MASTER) {
+            DefaultGroupHandler groupHandler =
+                    groupHandlerMap.get(link.src().deviceId());
+            if (groupHandler != null) {
+                groupHandler.linkUp(link);
+            }
+        }
+        defaultRoutingHandler.startPopulationProcess();
+    }
+
+    private void processLinkRemoved(Link link) {
+        log.debug("A link {} was removed", link.toString());
+        defaultRoutingHandler.startPopulationProcess();
+    }
+
+
+    private void processGroupAdded(Group group) {
+        log.debug("A new group with ID {} was added", group.id());
+        defaultRoutingHandler.resumePopulationProcess();
+    }
+
+    private void processDeviceAdded(Device device) {
+        log.debug("A new device with ID {} was added", device.id());
+        defaultRoutingHandler.populateTtpRules(device.id());
+        DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler(
+                device.id(), appId, new DeviceConfiguration(), linkService, groupService);
+        dgh.createGroups();
+        groupHandlerMap.put(device.id(), dgh);
+    }
+
+    private void processPortRemoved(Device device, Port port) {
+        log.debug("Port {} was removed", port.toString());
+        DefaultGroupHandler groupHandler =
+                groupHandlerMap.get(device.id());
+        if (groupHandler != null) {
+            groupHandler.portDown(port.number());
+        }
+    }
+}
