diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java b/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
index e69de29..fe4e6e3 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Open Networking Laboratory.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Apache License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ ******************************************************************************/
+
+package net.onrc.onos.apps.segmentrouting;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.api.packet.IPacketListener;
+import net.onrc.onos.api.packet.IPacketService;
+import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
+import net.onrc.onos.core.packet.ARP;
+import net.onrc.onos.core.packet.Ethernet;
+import net.onrc.onos.core.packet.IPv4;
+import net.onrc.onos.core.topology.ITopologyService;
+import net.onrc.onos.core.topology.MutableTopology;
+import net.onrc.onos.core.topology.Port;
+import net.onrc.onos.core.topology.Switch;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFPacketOut;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.U32;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.esotericsoftware.minlog.Log;
+
+/**
+ * Handling ARP requests to switches for Segment Routing.
+ * <p/>
+ * The module is for handling ARP requests to switches. It sends ARP response for any known
+ * hosts to the controllers.
+ * TODO: need to check the network config file for all hosts and packets
+ */
+public class ArpHandler implements IPacketListener  {
+
+    private static final Logger log = LoggerFactory
+            .getLogger(ArpHandler.class);
+
+    private IFloodlightProviderService floodlightProvider;
+    private IPacketService packetService;
+    private IFlowPusherService flowPusher;
+    private ITopologyService topologyService;
+    private MutableTopology mutableTopology;
+    //private List<ArpEntry> arpEntries;
+    private SegmentRoutingManager srManager;
+
+    private static final short IDLE_TIMEOUT = 0;
+    private static final short HARD_TIMEOUT = 0;
+
+    private static final int TABLE_VLAN = 0;
+    private static final int TABLE_TMAC = 1;
+    private static final int TABLE_IPv4_UNICAST = 2;
+    private static final int TABLE_MPLS = 3;
+    private static final int TABLE_META = 4;
+    private static final int TABLE_ACL = 5;
+
+    private static final short MAX_PRIORITY = (short) 0xffff;
+    private static final short SLASH_24_PRIORITY = (short) 0xfff0;
+    private static final short SLASH_16_PRIORITY = (short) 0xff00;
+    private static final short SLASH_8_PRIORITY = (short) 0xf000;
+    private static final short MIN_PRIORITY = 0x0;
+
+
+    /*
+     * Default Constructor
+     */
+    public ArpHandler(FloodlightModuleContext context, SegmentRoutingManager segmentRoutingManager) {
+
+        this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+        this.packetService = context.getServiceImpl(IPacketService.class);
+        this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
+        this.topologyService = context.getServiceImpl(ITopologyService.class);
+        this.srManager = segmentRoutingManager;
+        this.mutableTopology = topologyService.getTopology();
+
+        packetService.registerPacketListener(this);
+        //arpEntries = new ArrayList<ArpEntry>();
+
+        Log.debug("Arp Handler is initialized");
+
+    }
+
+    @Override
+    public void receive(Switch sw, Port inPort, Ethernet payload) {
+        log.debug("Received a packet {} from sw {} ", payload.toString(), sw.getDpid());
+
+        if (payload.getEtherType() == Ethernet.TYPE_ARP) {
+
+            ARP arp = (ARP)payload.getPayload();
+            srManager.updateArpCache(arp);
+
+            if (arp.getOpCode() == ARP.OP_REQUEST) {
+                handleArpRequest(sw, inPort, arp);
+            }
+            else {
+                byte[] senderMacAddressByte = arp.getSenderHardwareAddress();
+                String targetMacAddressStr = MacAddress.of(senderMacAddressByte).toString();
+                if (targetMacAddressStr.equals(sw.getStringAttribute("routerMac"))) {
+                    IPv4Address hostIpAddress = IPv4Address.of(arp.getSenderProtocolAddress());
+                    srManager.addRouteToHost(sw,hostIpAddress.getInt(), senderMacAddressByte);
+                }
+            }
+
+        }
+
+    }
+
+
+    /**
+     * Send an ARP response for the ARP request to the known switches
+     *
+     * @param sw Switch
+     * @param inPort port to send ARP response to
+     * @param arpRequest ARP request packet to handle
+     */
+    private void handleArpRequest(Switch sw, Port inPort, ARP arpRequest) {
+
+        List<String> subnetGatewayIPs = getSubnetGatewayIps(sw);
+        String switchMacAddressStr = sw.getStringAttribute("routerMac");
+        if (!subnetGatewayIPs.isEmpty()) {
+            IPv4Address targetProtocolAddress = IPv4Address.of(arpRequest.getTargetProtocolAddress());
+            // Do we have to check port also ??
+            if (subnetGatewayIPs.contains(targetProtocolAddress.toString())) {
+                MACAddress targetMac = MACAddress.valueOf(switchMacAddressStr);
+
+                ARP arpReply = new ARP();
+                arpReply.setHardwareType(ARP.HW_TYPE_ETHERNET)
+                        .setProtocolType(ARP.PROTO_TYPE_IP)
+                        .setHardwareAddressLength(
+                                (byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
+                        .setProtocolAddressLength((byte) IPv4.ADDRESS_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);
+
+                sendPacketOut(sw, eth, inPort.getPortNumber().shortValue());
+            }
+        }
+    }
+
+    /**
+     * Retrieve Gateway IP address of all subnets defined in net config file
+     *
+     * @param sw Switch to retrieve subnet GW IPs for
+     * @return list of GW IP addresses for all subnets
+     */
+    private List<String> getSubnetGatewayIps(Switch sw) {
+
+        List<String> gatewayIps = new ArrayList<String>();
+
+        String subnets = sw.getStringAttribute("subnets");
+        try {
+            JSONArray arry = new JSONArray(subnets);
+            for (int i = 0; i < arry.length(); i++) {
+                String subnetIpSlash = (String) arry.getJSONObject(i).get("subnetIp");
+                if (subnetIpSlash != null) {
+                    String subnetIp = subnetIpSlash.substring(0, subnetIpSlash.indexOf('/'));
+                    gatewayIps.add(subnetIp);
+                }
+            }
+        } catch (JSONException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        return gatewayIps;
+    }
+
+    /**
+     * Send an ARP request
+     *
+     * @param sw Switch
+     * @param targetAddress Target IP address
+     * @param inPort Port to send the ARP request
+     *
+     */
+    public void sendArpRequest(Switch sw, int targetAddressInt, Port inPort) {
+
+        IPv4Address targetAddress = IPv4Address.of(targetAddressInt);
+        String senderMacAddressStr = sw.getStringAttribute("routerMac");
+        String senderIpAddressSlash = sw.getStringAttribute("routerIp");
+        if (senderMacAddressStr == null || senderIpAddressSlash == null)
+            return;
+        String senderIpAddressStr =
+                senderIpAddressSlash.substring(0, senderIpAddressSlash.indexOf('/'));
+        byte[] senderMacAddress = MacAddress.of(senderMacAddressStr).getBytes();
+        byte[] senderIpAddress = IPv4Address.of(senderIpAddressStr).getBytes();
+
+        ARP arpRequest = new ARP();
+        arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
+                .setProtocolType(ARP.PROTO_TYPE_IP)
+                .setHardwareAddressLength(
+                        (byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
+                .setProtocolAddressLength((byte) IPv4.ADDRESS_LENGTH)
+                .setOpCode(ARP.OP_REQUEST)
+                .setSenderHardwareAddress(senderMacAddress)
+                .setTargetHardwareAddress(MacAddress.NONE.getBytes())
+                .setSenderProtocolAddress(senderIpAddress)
+                .setTargetProtocolAddress(targetAddress.getBytes());
+
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(MacAddress.BROADCAST.getBytes())
+                .setSourceMACAddress(senderMacAddress)
+                .setEtherType(Ethernet.TYPE_ARP).setPayload(arpRequest);
+
+        sendPacketOut(sw, eth, (short)-1);
+
+    }
+
+    /**
+     * Send PACKET_OUT packet to switch
+     *
+     * @param sw Switch to send the packet to
+     * @param packet Packet to send
+     * @param switchPort port to send (if -1, broadcast)
+     */
+    private void sendPacketOut(Switch sw, Ethernet packet, short port) {
+
+        IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
+        OFFactory factory = ofSwitch.getFactory();
+
+        List<OFAction> actions = new ArrayList<>();
+
+        if (port > 0) {
+            OFAction outport = factory.actions().output(OFPort.of(port), Short.MAX_VALUE);
+            actions.add(outport);
+        }
+        else {
+            Iterator<Port> iter = sw.getPorts().iterator();
+            while (iter.hasNext()) {
+                Port p = iter.next();
+                int pnum = p.getPortNumber().shortValue();
+                if (U32.of(pnum).compareTo(U32.of(OFPort.MAX.getPortNumber())) < 1) {
+                    OFAction outport = factory.actions().output(OFPort.of(p.getNumber().shortValue()),
+                            Short.MAX_VALUE);
+                    actions.add(outport);
+                }
+            }
+        }
+
+        OFPacketOut po = factory.buildPacketOut()
+                .setData(packet.serialize())
+                .setActions(actions)
+                .build();
+
+        flowPusher.add(sw.getDpid(), po);
+    }
+
+}
+
