diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisChannelHandler.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisChannelHandler.java
new file mode 100755
index 0000000..064176d
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisChannelHandler.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.isis.controller.impl;
+
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
+import org.jboss.netty.handler.timeout.ReadTimeoutException;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisLsdb;
+import org.onosproject.isis.controller.IsisMessage;
+import org.onosproject.isis.controller.IsisProcess;
+import org.onosproject.isis.controller.impl.lsdb.DefaultIsisLsdb;
+import org.onosproject.isis.exceptions.IsisParseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.channels.ClosedChannelException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * Channel handler deals with the ISIS channel connection.
+ * Also it dispatches messages to the appropriate handlers for processing.
+ */
+public class IsisChannelHandler extends IdleStateAwareChannelHandler {
+
+    private static final Logger log = LoggerFactory.getLogger(IsisChannelHandler.class);
+    private static Map<Integer, Object> isisDb = null;
+    private Channel channel;
+    private Controller controller;
+    private List<IsisProcess> processes = null;
+    private List<ScheduledExecutorService> executorList = new ArrayList<>();
+    private byte[] configPacket = null;
+    private Map<Integer, IsisInterface> isisInterfaceMap = new ConcurrentHashMap<>();
+    private IsisLsdb isisLsdb = new DefaultIsisLsdb();
+    private List<Ip4Address> interfaceIps = new ArrayList<>();
+
+    /**
+     * Creates an instance of ISIS channel handler.
+     *
+     * @param controller controller instance
+     * @param processes  list of configured processes
+     */
+    public IsisChannelHandler(Controller controller, List<IsisProcess> processes) {
+        this.controller = controller;
+        this.processes = processes;
+    }
+
+    /**
+     * Initializes the interface map with interface details.
+     */
+    public void initializeInterfaceMap() {
+        for (IsisProcess process : processes) {
+            for (IsisInterface isisInterface : process.isisInterfaceList()) {
+                isisInterfaceMap.put(isisInterface.interfaceIndex(), isisInterface);
+                interfaceIps.add(isisInterface.interfaceIpAddress());
+            }
+        }
+        //Initializes the interface with all interface ip details - for ls pdu generation
+        initializeInterfaceIpList();
+    }
+
+    /**
+     * Updates the interface map with interface details.
+     *
+     * @param isisProcesses updated process instances
+     */
+    public void updateInterfaceMap(List<IsisProcess> isisProcesses) {
+        for (IsisProcess isisUpdatedProcess : isisProcesses) {
+            for (IsisInterface isisUpdatedInterface : isisUpdatedProcess.isisInterfaceList()) {
+                IsisInterface isisInterface = isisInterfaceMap.get(isisUpdatedInterface.interfaceIndex());
+                if (isisInterface == null) {
+                    isisInterfaceMap.put(isisInterface.interfaceIndex(), isisInterface);
+                    interfaceIps.add(isisInterface.interfaceIpAddress());
+                } else {
+                    isisInterface.setReservedPacketCircuitType(isisUpdatedInterface.reservedPacketCircuitType());
+                    isisInterface.setNetworkType(isisUpdatedInterface.networkType());
+                    isisInterface.setHoldingTime(isisUpdatedInterface.holdingTime());
+                    isisInterface.setHelloInterval(isisUpdatedInterface.helloInterval());
+                    isisInterfaceMap.put(isisInterface.interfaceIndex(), isisInterface);
+                }
+            }
+        }
+    }
+
+    /**
+     * Initializes the interface with all interface ip details.
+     */
+    public void initializeInterfaceIpList() {
+        for (IsisProcess process : processes) {
+            for (IsisInterface isisInterface : process.isisInterfaceList()) {
+                ((DefaultIsisInterface) isisInterface).setAllConfiguredInterfaceIps(interfaceIps);
+            }
+        }
+    }
+
+    /**
+     * Initialize channel, start hello sender and initialize LSDB.
+     */
+    private void initialize() {
+        log.debug("IsisChannelHandler initialize..!!!");
+        if (configPacket != null) {
+            log.debug("IsisChannelHandler initialize -> sentConfig packet of length ::"
+                              + configPacket.length);
+            sentConfigPacket(configPacket);
+        }
+        //start the hello timer
+        startHelloSender();
+        //Initialize Database
+        isisLsdb.initializeDb();
+    }
+
+    @Override
+    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent evt) throws Exception {
+        log.info("ISIS channelConnected from {}", evt.getChannel().getRemoteAddress());
+        this.channel = evt.getChannel();
+        initialize();
+    }
+
+    @Override
+    public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent evt) {
+        log.debug("IsisChannelHandler::channelDisconnected...!!!");
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
+        log.info("[exceptionCaught]: " + e.toString());
+        if (e.getCause() instanceof ReadTimeoutException) {
+            log.error("Disconnecting device {} due to read timeout", e.getChannel().getRemoteAddress());
+            return;
+        } else if (e.getCause() instanceof ClosedChannelException) {
+            log.debug("Channel for ISIS {} already closed", e.getChannel().getRemoteAddress());
+        } else if (e.getCause() instanceof IOException) {
+            log.error("Disconnecting ISIS {} due to IO Error: {}", e.getChannel().getRemoteAddress(),
+                      e.getCause().getMessage());
+            if (log.isDebugEnabled()) {
+                log.debug("StackTrace for previous Exception: {}", e.getCause());
+            }
+        } else if (e.getCause() instanceof IsisParseException) {
+            IsisParseException errMsg = (IsisParseException) e.getCause();
+            byte errorCode = errMsg.errorCode();
+            byte errorSubCode = errMsg.errorSubCode();
+            log.error("Error while parsing message from ISIS {}, ErrorCode {}",
+                      e.getChannel().getRemoteAddress(), errorCode);
+        } else if (e.getCause() instanceof RejectedExecutionException) {
+            log.warn("Could not process message: queue full");
+        } else {
+            log.error("Error while processing message from ISIS {}",
+                      e.getChannel().getRemoteAddress());
+        }
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+        log.debug("IsisChannelHandler::messageReceived...!!!");
+        Object message = e.getMessage();
+        if (message instanceof List) {
+            List<IsisMessage> isisMessageList = (List<IsisMessage>) message;
+            log.debug("IsisChannelHandler::List of IsisMessages Size {}", isisMessageList.size());
+            if (isisMessageList != null) {
+                for (IsisMessage isisMessage : isisMessageList) {
+                    processIsisMessage(isisMessage, ctx);
+                }
+            } else {
+                log.debug("IsisChannelHandler::IsisMessages Null List...!!");
+            }
+        }
+        if (message instanceof IsisMessage) {
+            IsisMessage isisMessage = (IsisMessage) message;
+            log.debug("IsisChannelHandler::IsisMessages received...!!");
+            processIsisMessage(isisMessage, ctx);
+        }
+    }
+
+    /**
+     * When an ISIS message received it is handed over to this method.
+     * Based on the type of the ISIS message received it will be handed over
+     * to corresponding message handler methods.
+     *
+     * @param isisMessage received ISIS message
+     * @param ctx         channel handler context instance.
+     * @throws Exception might throws exception
+     */
+    public void processIsisMessage(IsisMessage isisMessage, ChannelHandlerContext ctx) throws Exception {
+        log.debug("IsisChannelHandler::processIsisMessage...!!!");
+        int interfaceIndex = isisMessage.interfaceIndex();
+        IsisInterface isisInterface = isisInterfaceMap.get(interfaceIndex);
+        isisInterface.processIsisMessage(isisMessage, isisLsdb, channel);
+    }
+
+    /**
+     * Starts the hello timer which sends hello packet every configured seconds.
+     */
+    public void startHelloSender() {
+        log.debug("IsisController::startHelloSender");
+        Set<Integer> interfaceIndexes = isisInterfaceMap.keySet();
+        for (Integer interfaceIndex : interfaceIndexes) {
+            IsisInterface isisInterface = isisInterfaceMap.get(interfaceIndex);
+            isisInterface.startHelloSender(channel);
+        }
+    }
+
+    /**
+     * Stops the hello timer.
+     */
+    public void stopHelloSender() {
+        log.debug("ISISChannelHandler::stopHelloTimer ");
+        for (ScheduledExecutorService exServiceHello : executorList) {
+            exServiceHello.shutdown();
+        }
+    }
+
+    /**
+     * Sends the interface configuration packet to server.
+     *
+     * @param configPacket interface configuration
+     */
+    public void sentConfigPacket(byte[] configPacket) {
+        if (channel != null) {
+            channel.write(configPacket);
+            log.debug("IsisChannelHandler sentConfigPacket packet sent..!!!");
+        } else {
+            log.debug("IsisChannelHandler sentConfigPacket channel not connected - re try..!!!");
+            this.configPacket = configPacket;
+        }
+    }
+}
\ No newline at end of file
