diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/OfOverlayWorkflow.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/OfOverlayWorkflow.java
new file mode 100644
index 0000000..5fb8cd2
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/OfOverlayWorkflow.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ofoverlay.impl;
+
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.workflow.api.ImmutableListWorkflow;
+import org.onosproject.workflow.api.Workflow;
+import org.onosproject.workflow.api.WorkflowExecutionService;
+import org.onosproject.workflow.api.WorkflowStore;
+import org.onosproject.workflow.api.WorkplaceStore;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.URI;
+import java.util.concurrent.ScheduledExecutorService;
+
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * Class for Open-flow overlay configuration workflow.
+ */
+@Component(immediate = true)
+public class OfOverlayWorkflow {
+
+    private static final Logger log = LoggerFactory.getLogger(OfOverlayWorkflow.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected WorkflowStore workflowStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected WorkplaceStore workplaceStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected WorkflowExecutionService workflowExecutionService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected DeviceService deviceService;
+
+    private ScheduledExecutorService eventMapTriggerExecutor;
+
+    @Activate
+    public void activate() {
+        log.info("Activated");
+
+        eventMapTriggerExecutor = newSingleThreadScheduledExecutor(
+                groupedThreads("onos/of-overlay", "eventmap-trigger-executor"));
+
+        registerWorkflows();
+
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Deactivated");
+    }
+
+    /**
+     * Registers workflows.
+     */
+    private void registerWorkflows() {
+        // registering class-loader
+        workflowStore.registerLocal(this.getClass().getClassLoader());
+
+        // registering new workflow definition
+        URI uri = URI.create("of-overlay.workflow-nova");
+        Workflow workflow = ImmutableListWorkflow.builder()
+                .id(uri)
+                //.attribute(WorkflowAttribute.REMOVE_AFTER_COMPLETE)
+                .chain(Ovs.CreateOvsdbDevice.class.getName())
+                .chain(Ovs.UpdateOvsVersion.class.getName())
+                .chain(Ovs.UpdateOverlayBridgeId.class.getName())
+                .chain(Ovs.CreateOverlayBridge.class.getName())
+                .chain(Ovs.UpdateUnderlayBridgeId.class.getName())
+                .chain(Ovs.CreateUnderlayBridge.class.getName())
+                .chain(Ovs.CreateOverlayBridgeVxlanPort.class.getName())
+                .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName())
+                .chain(Ovs.ConfigureUnderlayBridgeLocalIp.class.getName())
+                .build();
+        workflowStore.register(workflow);
+
+        uri = URI.create("of-overlay.clean-workflow-nova");
+        workflow = ImmutableListWorkflow.builder()
+                .id(uri)
+                //.attribute(WorkflowAttribute.REMOVE_AFTER_COMPLETE)
+                .chain(Ovs.DeleteOverlayBridgeConfig.class.getName())
+                .chain(Ovs.RemoveOverlayBridgeOfDevice.class.getName())
+                .chain(Ovs.DeleteUnderlayBridgeConfig.class.getName())
+                .chain(Ovs.RemoveUnderlayBridgeOfDevice.class.getName())
+                .chain(Ovs.RemoveOvsdbDevice.class.getName())
+                .build();
+        workflowStore.register(workflow);
+
+        uri = URI.create("of-overlay.workflow-ovs-leaf");
+        workflow = ImmutableListWorkflow.builder()
+                .id(uri)
+                .chain(Ovs.CreateOvsdbDevice.class.getName())
+                .chain(Ovs.UpdateOvsVersion.class.getName())
+                .chain(Ovs.UpdateUnderlayBridgeId.class.getName())
+                .chain(Ovs.CreateUnderlayBridge.class.getName())
+                .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName())
+                .build();
+        workflowStore.register(workflow);
+
+        uri = URI.create("of-overlay.workflow-ovs-spine");
+        workflow = ImmutableListWorkflow.builder()
+                .id(uri)
+                .chain(Ovs.CreateOvsdbDevice.class.getName())
+                .chain(Ovs.UpdateOvsVersion.class.getName())
+                .chain(Ovs.UpdateUnderlayBridgeId.class.getName())
+                .chain(Ovs.CreateUnderlayBridge.class.getName())
+                .chain(Ovs.AddPhysicalPortsOnUnderlayBridge.class.getName())
+                .build();
+        workflowStore.register(workflow);
+
+        deviceService.addListener(
+                event -> {
+                    // trigger EventTask for DeviceEvent
+                    eventMapTriggerExecutor.submit(
+                            () -> workflowExecutionService.eventMapTrigger(
+                                    event,
+                                    // event hint supplier
+                                    (ev) -> {
+                                        if (ev == null || ev.subject() == null) {
+                                            return null;
+                                        }
+                                        String hint = event.subject().id().toString();
+                                        log.debug("hint: {}", hint);
+                                        return hint;
+                                    }
+                            )
+                    );
+                }
+        );
+
+    }
+
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/Ovs.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/Ovs.java
new file mode 100644
index 0000000..428688b
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/Ovs.java
@@ -0,0 +1,1220 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ofoverlay.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.TpPort;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.event.Event;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.behaviour.BridgeConfig;
+import org.onosproject.net.behaviour.BridgeDescription;
+import org.onosproject.net.behaviour.BridgeName;
+import org.onosproject.net.behaviour.ControlProtocolVersion;
+import org.onosproject.net.behaviour.ControllerInfo;
+import org.onosproject.net.behaviour.DefaultBridgeDescription;
+import org.onosproject.net.behaviour.DefaultTunnelDescription;
+import org.onosproject.net.behaviour.InterfaceConfig;
+import org.onosproject.net.behaviour.TunnelDescription;
+import org.onosproject.net.behaviour.TunnelEndPoints;
+import org.onosproject.net.behaviour.TunnelKeys;
+import org.onosproject.net.device.DeviceAdminService;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.Behaviour;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.ofoverlay.impl.util.NetworkAddress;
+import org.onosproject.ofoverlay.impl.util.OvsDatapathType;
+import org.onosproject.ofoverlay.impl.util.OvsVersion;
+import org.onosproject.ofoverlay.impl.util.SshUtil;
+import org.onosproject.ovsdb.controller.OvsdbClientService;
+import org.onosproject.ovsdb.controller.OvsdbController;
+import org.onosproject.ovsdb.controller.OvsdbNodeId;
+import org.onosproject.workflow.api.AbstractWorklet;
+import org.onosproject.workflow.api.JsonDataModel;
+import org.onosproject.workflow.api.WorkflowContext;
+import org.onosproject.workflow.api.WorkflowException;
+import org.onosproject.workflow.model.accessinfo.SshAccessInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.onosproject.net.AnnotationKeys.PORT_NAME;
+import static org.onosproject.workflow.api.CheckCondition.check;
+
+/**
+ * Class for defining OVS workflows.
+ */
+public final class Ovs {
+
+    private static final Logger log = LoggerFactory.getLogger(Ovs.class);
+
+    private static final String MODEL_MGMT_IP = "/mgmtIp";
+    private static final String MODEL_OVSDB_PORT = "/ovsdbPort";
+    private static final String MODEL_OVS_VERSION = "/ovsVersion";
+    private static final String MODEL_OVS_DATAPATH_TYPE = "/ovsDatapathType";
+    private static final String MODEL_SSH_ACCESSINFO = "/sshAccessInfo";
+    private static final String MODEL_OF_DEVID_OVERLAY_BRIDGE = "/ofDevIdBrInt";
+    private static final String MODEL_OF_DEVID_UNDERLAY_BRIDGE = "/ofDevIdBrPhy";
+    private static final String MODEL_PHY_PORTS = "/physicalPorts";
+    private static final String MODEL_VTEP_IP = "/vtepIp";
+
+    private static final String BRIDGE_OVERLAY = "br-int";
+    private static final String BRIDGE_UNDERLAY = "br-phy";
+
+    private static final int DEVID_IDX_BRIDGE_OVERLAY = 0;
+    private static final int DEVID_IDX_BRIDGE_UNDERLAY_NOVA = 1;
+
+    private static final ControlProtocolVersion BRIDGE_DEFAULT_OF_VERSION = ControlProtocolVersion.OF_1_3;
+    private static final int    OPENFLOW_PORT = 6653;
+    private static final String OPENFLOW_CHANNEL_PROTO = "tcp";
+    private static final String OVSDB_DEVICE_PREFIX = "ovsdb:";
+
+    private static final long TIMEOUT_DEVICE_CREATION_MS = 60000L;
+    private static final long TIMEOUT_PORT_ADDITION_MS = 120000L;
+
+
+    /**
+     * Utility class for OVS workflow.
+     */
+    public static final class OvsUtil {
+
+        private OvsUtil() {
+
+        }
+
+        private static final String OPENFLOW_DEVID_FORMAT = "of:%08x%08x";
+
+        /**
+         * Builds Open-flow device id with ip address, and index.
+         * @param addr ip address
+         * @param index index
+         * @return created device id
+         */
+        public static DeviceId buildOfDeviceId(IpAddress addr, int index) {
+            if (addr.isIp4()) {
+                Ip4Address v4Addr = addr.getIp4Address();
+                return DeviceId.deviceId(String.format(OPENFLOW_DEVID_FORMAT, v4Addr.toInt(), index));
+            } else if (addr.isIp6()) {
+                Ip6Address v6Addr = addr.getIp6Address();
+                return DeviceId.deviceId(String.format(OPENFLOW_DEVID_FORMAT, v6Addr.hashCode(), index));
+            } else {
+                return DeviceId.deviceId(String.format(OPENFLOW_DEVID_FORMAT, addr.hashCode(), index));
+            }
+        }
+
+        /**
+         * Builds OVS data path type.
+         * @param strOvsDatapathType string ovs data path type
+         * @return ovs data path type
+         * @throws WorkflowException workflow exception
+         */
+        public static final OvsDatapathType buildOvsDatapathType(String strOvsDatapathType) throws WorkflowException {
+            try {
+                return OvsDatapathType.valueOf(strOvsDatapathType.toUpperCase());
+            } catch (IllegalArgumentException e) {
+                throw new WorkflowException(e);
+            }
+        }
+
+        /**
+         * Gets OVSDB behavior.
+         * @param context workflow context
+         * @param mgmtIp management ip
+         * @param behaviourClass behavior class
+         * @param <T> behavior class
+         * @return OVSDB behavior
+         * @throws WorkflowException workflow exception
+         */
+        public static final <T extends Behaviour> T getOvsdbBehaviour(WorkflowContext context, String mgmtIp,
+                                                                    Class<T> behaviourClass) throws WorkflowException {
+
+            DriverService driverService = context.getService(DriverService.class);
+
+            DeviceId devId = ovsdbDeviceId(mgmtIp);
+            DriverHandler handler = driverService.createHandler(devId);
+            if (Objects.isNull(handler)) {
+                throw new WorkflowException("Failed to get DriverHandler for " + devId);
+            }
+            T behaviour;
+            try {
+                behaviour =  handler.behaviour(behaviourClass);
+                if (Objects.isNull(behaviour)) {
+                    throw new WorkflowException("Failed to get " + behaviourClass + " for " + devId + "-" + handler);
+                }
+            } catch (IllegalArgumentException e) {
+                throw new WorkflowException("Failed to get " + behaviourClass + " for " + devId + "-" + handler);
+            }
+            return behaviour;
+        }
+
+        /**
+         * Gets bridge description.
+         * @param bridgeConfig bridge config
+         * @param bridgeName bridge name
+         * @return bridge description optional
+         */
+        public static final Optional<BridgeDescription> getBridgeDescription(BridgeConfig bridgeConfig,
+                                                                             String bridgeName) {
+            try {
+                Collection<BridgeDescription> bridges = bridgeConfig.getBridges();
+                for (BridgeDescription br: bridges) {
+                    if (Objects.equals(bridgeName, br.name())) {
+                        return Optional.of(br);
+                    }
+                }
+            } catch (Exception e) {
+                log.error("Exception : ", e);
+            }
+            return Optional.empty();
+        }
+
+        /**
+         * Builds OVSDB device id.
+         * @param mgmtIp management ip address string
+         * @return OVSDB device id
+         */
+        public static final DeviceId ovsdbDeviceId(String mgmtIp) {
+            return DeviceId.deviceId(OVSDB_DEVICE_PREFIX.concat(mgmtIp));
+        }
+
+        /**
+         * Returns {@code true} if this bridge is available;
+         * returns {@code false} otherwise.
+         * @param context workflow context
+         * @param devId device id
+         * @return {@code true} if this bridge is available; {@code false} otherwise.
+         * @throws WorkflowException workflow exception
+         */
+        public static final boolean isAvailableBridge(WorkflowContext context, DeviceId devId)
+                throws WorkflowException {
+
+            if (Objects.isNull(devId)) {
+                throw new WorkflowException("Invalid device id in data model");
+            }
+
+            DeviceService deviceService = context.getService(DeviceService.class);
+            Device dev = deviceService.getDevice(devId);
+            if (Objects.isNull(dev)) {
+                return false;
+            }
+
+            return deviceService.isAvailable(devId);
+        }
+
+        /**
+         * Gets openflow controller information list.
+         * @param context workflow context
+         * @return openflow controller information list
+         * @throws WorkflowException workflow exception
+         */
+        public static final List<ControllerInfo> getOpenflowControllerInfoList(WorkflowContext context)
+                throws WorkflowException {
+            ClusterService clusterService = context.getService(ClusterService.class);
+            java.util.List<org.onosproject.net.behaviour.ControllerInfo> controllers = new ArrayList<>();
+            Sets.newHashSet(clusterService.getNodes()).forEach(
+                    controller -> {
+                        org.onosproject.net.behaviour.ControllerInfo ctrlInfo =
+                                new org.onosproject.net.behaviour.ControllerInfo(controller.ip(),
+                                        OPENFLOW_PORT,
+                                        OPENFLOW_CHANNEL_PROTO);
+                        controllers.add(ctrlInfo);
+                    }
+            );
+            return controllers;
+        }
+
+        /**
+         * Creates bridge.
+         * @param bridgeConfig bridge config
+         * @param name bridge name to create
+         * @param dpid openflow data path id of bridge to create
+         * @param ofControllers openflow controller information list
+         * @param datapathType OVS data path type
+         */
+        public static final void createBridge(BridgeConfig bridgeConfig, String name, String dpid,
+                                              List<ControllerInfo> ofControllers, OvsDatapathType datapathType) {
+            BridgeDescription.Builder bridgeDescBuilder = DefaultBridgeDescription.builder()
+                    .name(name)
+                    .failMode(BridgeDescription.FailMode.SECURE)
+                    .datapathId(dpid)
+                    .disableInBand()
+                    .controlProtocols(Collections.singletonList(BRIDGE_DEFAULT_OF_VERSION))
+                    .controllers(ofControllers);
+
+            if (datapathType != null && !(datapathType.equals(OvsDatapathType.EMPTY))) {
+                bridgeDescBuilder.datapathType(datapathType.toString());
+                log.info("create {} with dataPathType {}", name, datapathType);
+            }
+
+            BridgeDescription bridgeDesc = bridgeDescBuilder.build();
+            bridgeConfig.addBridge(bridgeDesc);
+        }
+
+        /**
+         * Index of data path id in openflow device id.
+         */
+        private static final int DPID_BEGIN_INDEX = 3;
+
+        /**
+         * Gets bridge data path id.
+         * @param devId device id
+         * @return bridge data path id
+         */
+        public static final String bridgeDatapathId(DeviceId devId) {
+            return devId.toString().substring(DPID_BEGIN_INDEX);
+        }
+
+        /**
+         * Gets OVSDB client.
+         * @param context workflow context
+         * @param strMgmtIp management ip address
+         * @param intOvsdbPort OVSDB port
+         * @return ovsdb client
+         * @throws WorkflowException workflow exception
+         */
+        public static final OvsdbClientService getOvsdbClient(
+                WorkflowContext context, String strMgmtIp, int intOvsdbPort) throws WorkflowException {
+            IpAddress mgmtIp = IpAddress.valueOf(strMgmtIp);
+            TpPort ovsdbPort = TpPort.tpPort(intOvsdbPort);
+            OvsdbController ovsdbController = context.getService(OvsdbController.class);
+            return ovsdbController.getOvsdbClient(new OvsdbNodeId(mgmtIp, ovsdbPort.toInt()));
+        }
+
+        /**
+         * Checks whether 2 controller informations include same controller information.
+         * @param a controller information list
+         * @param b controller information list
+         * @return {@code true} if 2 controller informations include same controller information
+         */
+        public static boolean isEqual(List<ControllerInfo> a, List<ControllerInfo> b) {
+            if (a == b) {
+                return true;
+            } else if (a == null) {
+                // equivalent to (a == null && b != null)
+                return false;
+            } else if (b == null) {
+                // equivalent to (a != null && b == null)
+                return false;
+            } else if (a.size() != b.size()) {
+                return false;
+            }
+
+            return a.containsAll(b);
+        }
+
+        /**
+         * Gets the name of the port.
+         * @param port port
+         * @return the name of the port
+         */
+        public static final String portName(Port port) {
+            return port.annotations().value(PORT_NAME);
+        }
+    }
+
+    /**
+     * Work-let class for creating OVSDB device.
+     */
+    public static class CreateOvsdbDevice extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OVSDB_PORT)
+        Integer intOvsdbPort;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            OvsdbClientService ovsdbClient = OvsUtil.getOvsdbClient(context, strMgmtIp, intOvsdbPort);
+            return ovsdbClient == null || !ovsdbClient.isConnected();
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+            IpAddress mgmtIp = IpAddress.valueOf(strMgmtIp);
+            TpPort ovsdbPort = TpPort.tpPort(intOvsdbPort);
+            OvsdbController ovsdbController = context.getService(OvsdbController.class);
+            context.waitCompletion(DeviceEvent.class, OVSDB_DEVICE_PREFIX.concat(strMgmtIp),
+                    () -> ovsdbController.connect(mgmtIp, ovsdbPort),
+                    TIMEOUT_DEVICE_CREATION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            Device device = deviceEvent.subject();
+            switch (deviceEvent.type()) {
+                case DEVICE_ADDED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                case DEVICE_UPDATED:
+                    return context.getService(DeviceService.class).isAvailable(device.id());
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+
+
+    /**
+     * Work-let class for removing OVSDB device.
+     */
+    public static class RemoveOvsdbDevice extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            DeviceId devId = DeviceId.deviceId(OVSDB_DEVICE_PREFIX.concat(strMgmtIp));
+
+            Device dev = context.getService(DeviceService.class).getDevice(devId);
+            return dev != null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+            IpAddress mgmtIp = IpAddress.valueOf(strMgmtIp);
+            check(mgmtIp != null, "mgmt ip is invalid");
+            DeviceId devId = DeviceId.deviceId(OVSDB_DEVICE_PREFIX.concat(strMgmtIp));
+            DeviceAdminService adminService = context.getService(DeviceAdminService.class);
+
+            context.waitCompletion(DeviceEvent.class, devId.toString(),
+                    () -> adminService.removeDevice(devId),
+                    TIMEOUT_DEVICE_CREATION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            switch (deviceEvent.type()) {
+                case DEVICE_REMOVED:
+                    return !isNext(context);
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+
+    /**
+     * Work-let class for updating OVS version.
+     */
+    public static class UpdateOvsVersion extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_OVS_VERSION, optional = true)
+        String strOvsVersion;
+
+        @JsonDataModel(path = MODEL_SSH_ACCESSINFO)
+        JsonNode strSshAccessInfo;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            return strOvsVersion == null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            SshAccessInfo sshAccessInfo = SshAccessInfo.valueOf(strSshAccessInfo);
+            check(Objects.nonNull(sshAccessInfo), "Invalid ssh access info " + context.data());
+
+            OvsVersion ovsVersion = SshUtil.exec(sshAccessInfo,
+                    session -> SshUtil.fetchOvsVersion(session));
+
+            check(Objects.nonNull(ovsVersion), "Failed to fetch ovs version " + context.data());
+            strOvsVersion = ovsVersion.toString();
+
+            context.completed();
+        }
+    }
+
+    /**
+     * Work-let class for updating overlay bridge device id.
+     */
+    public static class UpdateOverlayBridgeId extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_OVERLAY_BRIDGE, optional = true)
+        String strOfDevIdOverlay;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            return strOfDevIdOverlay == null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+            Optional<BridgeDescription> optBd = OvsUtil.getBridgeDescription(bridgeConfig, BRIDGE_OVERLAY);
+            if (optBd.isPresent()) {
+                Optional<DeviceId> optDevId = optBd.get().deviceId();
+                if (optDevId.isPresent()) {
+                    log.info("Updates {} of device id with existing device id {}", BRIDGE_OVERLAY, optDevId.get());
+                    strOfDevIdOverlay = optDevId.get().toString();
+                } else {
+                    DeviceId newDevId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_OVERLAY);
+                    log.info("Failed to find devId. Updates {} of device id with new device id {}",
+                            BRIDGE_OVERLAY, newDevId);
+                    strOfDevIdOverlay = newDevId.toString();
+                }
+            } else {
+                DeviceId newDevId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_OVERLAY);
+                log.info("Failed to find description. Updates {} of device id with new device id {}",
+                        BRIDGE_OVERLAY, newDevId);
+                strOfDevIdOverlay = newDevId.toString();
+            }
+
+            context.completed();
+        }
+    }
+
+    /**
+     * Work-let class for creating overlay openflow bridge.
+     */
+    public static class CreateOverlayBridge extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OVSDB_PORT)
+        Integer intOvsdbPort;
+
+        @JsonDataModel(path = MODEL_OVS_DATAPATH_TYPE)
+        String strOvsDatapath;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_OVERLAY_BRIDGE, optional = true)
+        String strOfDevIdOverlay;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay");
+            return !OvsUtil.isAvailableBridge(context, DeviceId.deviceId(strOfDevIdOverlay));
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay");
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+            List<ControllerInfo> ofControllers = OvsUtil.getOpenflowControllerInfoList(context);
+            DeviceId ofDeviceId = DeviceId.deviceId(strOfDevIdOverlay);
+
+            if (ofControllers == null || ofControllers.size() == 0) {
+                throw new WorkflowException("Invalid of controllers");
+            }
+
+            Optional<BridgeDescription> optBd = OvsUtil.getBridgeDescription(bridgeConfig, BRIDGE_OVERLAY);
+            if (!optBd.isPresent()) {
+
+                // If bridge does not exist, just creates a new bridge.
+                context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+                        () -> OvsUtil.createBridge(bridgeConfig,
+                                BRIDGE_OVERLAY,
+                                OvsUtil.bridgeDatapathId(ofDeviceId),
+                                ofControllers,
+                                OvsUtil.buildOvsDatapathType(strOvsDatapath)),
+                        TIMEOUT_DEVICE_CREATION_MS
+                );
+                return;
+
+            } else {
+                BridgeDescription bd = optBd.get();
+                if (OvsUtil.isEqual(ofControllers, bd.controllers())) {
+                    log.error("{} has valid controller setting({})", BRIDGE_OVERLAY, bd.controllers());
+                    context.completed();
+                    return;
+                }
+
+                OvsdbClientService ovsdbClient = OvsUtil.getOvsdbClient(context, strMgmtIp, intOvsdbPort);
+                if (ovsdbClient == null || !ovsdbClient.isConnected()) {
+                    throw new WorkflowException("Invalid ovsdb client for " + strMgmtIp);
+                }
+
+                // If controller settings are not matched, set controller with valid controller information.
+                context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+                        () -> ovsdbClient.setControllersWithDeviceId(bd.deviceId().get(), ofControllers),
+                        TIMEOUT_DEVICE_CREATION_MS
+                );
+                return;
+            }
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            Device device = deviceEvent.subject();
+            switch (deviceEvent.type()) {
+                case DEVICE_ADDED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                case DEVICE_UPDATED:
+                    return context.getService(DeviceService.class).isAvailable(device.id());
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+
+    /**
+     * Work-let class for updating underlay bridge device id.
+     */
+    public static class UpdateUnderlayBridgeId extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_UNDERLAY_BRIDGE, optional = true)
+        String strOfDevIdUnderlay;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            return strOfDevIdUnderlay == null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+            Optional<BridgeDescription> optBd = OvsUtil.getBridgeDescription(bridgeConfig, BRIDGE_UNDERLAY);
+            if (optBd.isPresent()) {
+                Optional<DeviceId> optDevId = optBd.get().deviceId();
+                if (optDevId.isPresent()) {
+                    log.info("Updates {} of device id with existing device id {}", BRIDGE_UNDERLAY, optDevId.get());
+                    strOfDevIdUnderlay = optDevId.get().toString();
+                } else {
+                    DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp),
+                            DEVID_IDX_BRIDGE_UNDERLAY_NOVA);
+                    log.info("Failed to find devId. Updates {} of device id with new device id {}",
+                            BRIDGE_UNDERLAY, devId);
+                    strOfDevIdUnderlay = devId.toString();
+                }
+            } else {
+                DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_UNDERLAY_NOVA);
+                log.info("Failed to find description. Updates {} of device id with new device id {}",
+                        BRIDGE_UNDERLAY, devId);
+                strOfDevIdUnderlay = devId.toString();
+            }
+
+            context.completed();
+        }
+    }
+
+    /**
+     * Work-let class for creating underlay openflow bridge.
+     */
+    public static class CreateUnderlayBridge extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OVSDB_PORT)
+        Integer intOvsdbPort;
+
+        @JsonDataModel(path = MODEL_OVS_DATAPATH_TYPE)
+        String strOvsDatapath;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_UNDERLAY_BRIDGE)
+        String strOfDevIdUnderlay;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdUnderlay != null, "invalid strOfDevIdUnderlay");
+            return !OvsUtil.isAvailableBridge(context, DeviceId.deviceId(strOfDevIdUnderlay));
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdUnderlay != null, "invalid strOfDevIdUnderlay");
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+            List<ControllerInfo> ofControllers = OvsUtil.getOpenflowControllerInfoList(context);
+            DeviceId ofDeviceId = DeviceId.deviceId(strOfDevIdUnderlay);
+
+            if (ofControllers == null || ofControllers.size() == 0) {
+                throw new WorkflowException("Invalid of controllers");
+            }
+
+            Optional<BridgeDescription> optBd = OvsUtil.getBridgeDescription(bridgeConfig, BRIDGE_UNDERLAY);
+            if (!optBd.isPresent()) {
+
+                // If bridge does not exist, just creates a new bridge.
+                context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+                        () -> OvsUtil.createBridge(bridgeConfig,
+                                BRIDGE_UNDERLAY,
+                                OvsUtil.bridgeDatapathId(ofDeviceId),
+                                ofControllers,
+                                OvsUtil.buildOvsDatapathType(strOvsDatapath)),
+                        TIMEOUT_DEVICE_CREATION_MS
+                );
+                return;
+
+            } else {
+                BridgeDescription bd = optBd.get();
+                if (OvsUtil.isEqual(ofControllers, bd.controllers())) {
+                    log.error("{} has valid controller setting({})", BRIDGE_UNDERLAY, bd.controllers());
+                    context.completed();
+                    return;
+                }
+
+                OvsdbClientService ovsdbClient = OvsUtil.getOvsdbClient(context, strMgmtIp, intOvsdbPort);
+                if (ovsdbClient == null || !ovsdbClient.isConnected()) {
+                    throw new WorkflowException("Invalid ovsdb client for " + strMgmtIp);
+                }
+
+                // If controller settings are not matched, set controller with valid controller information.
+                context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+                        () -> ovsdbClient.setControllersWithDeviceId(bd.deviceId().get(), ofControllers),
+                        TIMEOUT_DEVICE_CREATION_MS
+                );
+                return;
+            }
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            Device device = deviceEvent.subject();
+            switch (deviceEvent.type()) {
+                case DEVICE_ADDED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                case DEVICE_UPDATED:
+                    return context.getService(DeviceService.class).isAvailable(device.id());
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+
+    }
+
+    /**
+     * Work-let class for creating vxlan port on the overlay bridge.
+     */
+    public static class CreateOverlayBridgeVxlanPort extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_OVERLAY_BRIDGE, optional = true)
+        String strOfDevIdOverlay;
+
+        private static final String OVS_VXLAN_PORTNAME = "vxlan";
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay");
+            DeviceId deviceId = DeviceId.deviceId(strOfDevIdOverlay);
+            if (Objects.isNull(deviceId)) {
+                throw new WorkflowException("Invalid br-int bridge, before creating VXLAN port");
+            }
+
+            DeviceService deviceService = context.getService(DeviceService.class);
+            return !deviceService.getPorts(deviceId)
+                    .stream()
+                    .filter(port -> OvsUtil.portName(port).contains(OVS_VXLAN_PORTNAME) && port.isEnabled())
+                    .findAny().isPresent();
+        }
+
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            check(strOfDevIdOverlay != null, "invalid strOfDevIdOverlay");
+            TunnelDescription description = DefaultTunnelDescription.builder()
+                    .deviceId(BRIDGE_OVERLAY)
+                    .ifaceName(OVS_VXLAN_PORTNAME)
+                    .type(TunnelDescription.Type.VXLAN)
+                    .remote(TunnelEndPoints.flowTunnelEndpoint())
+                    .key(TunnelKeys.flowTunnelKey())
+                    .build();
+
+            DeviceId ofDeviceId = DeviceId.deviceId(strOfDevIdOverlay);
+            InterfaceConfig interfaceConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, InterfaceConfig.class);
+
+            context.waitCompletion(DeviceEvent.class, ofDeviceId.toString(),
+                    () -> interfaceConfig.addTunnelMode(BRIDGE_OVERLAY, description),
+                    TIMEOUT_DEVICE_CREATION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            switch (deviceEvent.type()) {
+                case PORT_ADDED:
+                    return !isNext(context);
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+
+    /**
+     * Work-let class for adding physical ports on the underlay openflow bridge.
+     */
+    public static class AddPhysicalPortsOnUnderlayBridge extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @JsonDataModel(path = MODEL_OVSDB_PORT)
+        Integer intOvsdbPort;
+
+        @JsonDataModel(path = MODEL_OF_DEVID_UNDERLAY_BRIDGE, optional = true)
+        String strOfDevIdUnderlay;
+
+        @JsonDataModel(path = MODEL_OVS_DATAPATH_TYPE)
+        String strOvsDatapath;
+
+        @JsonDataModel(path = MODEL_PHY_PORTS)
+        ArrayNode arrNodePhysicalPorts;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+            check(strOfDevIdUnderlay != null, "invalid strOfDevIdUnderlay");
+            DeviceId brphyDevId = DeviceId.deviceId(strOfDevIdUnderlay);
+            return !hasAllPhysicalPorts(context, brphyDevId);
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+            check(strOfDevIdUnderlay != null, "invalid strOfDevIdUnderlay");
+            DeviceId brphyDevId = DeviceId.deviceId(strOfDevIdUnderlay);
+
+            context.waitCompletion(DeviceEvent.class, brphyDevId.toString(),
+                    () -> addPhysicalPorts(context, brphyDevId, BRIDGE_UNDERLAY, strOvsDatapath),
+                    TIMEOUT_PORT_ADDITION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            switch (deviceEvent.type()) {
+                case PORT_ADDED:
+                    return !isNext(context);
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+
+        private final List<String> getPhysicalPorts(WorkflowContext context) throws WorkflowException {
+            List<String> ports = Lists.newArrayList();
+            for (JsonNode jsonNode : arrNodePhysicalPorts) {
+                check(jsonNode instanceof TextNode, "Invalid physical ports " + arrNodePhysicalPorts);
+                ports.add(jsonNode.asText());
+            }
+            return ports;
+        }
+
+        private final boolean hasAllPhysicalPorts(WorkflowContext context, DeviceId devId) throws WorkflowException {
+
+            List<Port> devPorts = context.getService(DeviceService.class).getPorts(devId);
+            check(devPorts != null, "Invalid device ports for " + devId);
+            List<String> physicalPorts = getPhysicalPorts(context);
+            check(physicalPorts != null, "Invalid physical ports" + context);
+
+            log.info("physicalPorts: {} for {}", physicalPorts, devId);
+            for (String port: physicalPorts) {
+                if (devPorts.stream().noneMatch(p -> OvsUtil.portName(p).contains(port))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private final boolean hasPort(WorkflowContext context, DeviceId devId, String portName)
+                throws WorkflowException {
+
+            List<Port> devPorts = context.getService(DeviceService.class).getPorts(devId);
+            check(devPorts != null, "Invalid device ports for " + devId);
+            return devPorts.stream().anyMatch(p -> OvsUtil.portName(p).contains(portName));
+        }
+
+        private final void addPhysicalPorts(WorkflowContext context, DeviceId devId, String bridgeName,
+                                            String strOvsDatapathType)
+                throws WorkflowException {
+            OvsdbClientService ovsdbClient = OvsUtil.getOvsdbClient(context, strMgmtIp, intOvsdbPort);
+            check(ovsdbClient != null, "Invalid ovsdb client");
+
+            List<String> physicalPorts = getPhysicalPorts(context);
+            check(physicalPorts != null, "Invalid physical ports");
+
+            OvsDatapathType datapathType = OvsUtil.buildOvsDatapathType(strOvsDatapathType);
+            check(datapathType != null, "Invalid data path type");
+
+            List<String> sortedPhyPorts = physicalPorts.stream().sorted().collect(Collectors.toList());
+
+            for (String port: sortedPhyPorts) {
+                if (hasPort(context, devId, port)) {
+                    continue;
+                }
+                log.info("adding port {} on {}", port, devId);
+                switch (datapathType) {
+                    case NETDEV:
+                        throw new WorkflowException("NETDEV datapathType are not supported");
+                        //break;
+                    case SYSTEM:
+                    default:
+                        ovsdbClient.createPort(BridgeName.bridgeName(bridgeName).name(), port);
+                }
+            }
+        }
+    }
+
+    /**
+     * Work-let class for configure local ip of underlay openflow bridge.
+     */
+    public static class ConfigureUnderlayBridgeLocalIp extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_SSH_ACCESSINFO)
+        JsonNode strSshAccessInfo;
+
+        @JsonDataModel(path = MODEL_VTEP_IP)
+        String strVtepIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            SshAccessInfo sshAccessInfo = SshAccessInfo.valueOf(strSshAccessInfo);
+            check(Objects.nonNull(sshAccessInfo), "Invalid ssh access info " + context.data());
+
+            NetworkAddress vtepIp = NetworkAddress.valueOf(strVtepIp);
+            check(Objects.nonNull(vtepIp), "Invalid vtep ip " + context.data());
+
+            return !SshUtil.exec(sshAccessInfo,
+                    session ->
+                            SshUtil.hasIpAddrOnInterface(session, BRIDGE_UNDERLAY, vtepIp)
+                                    && SshUtil.isIpLinkUpOnInterface(session, BRIDGE_UNDERLAY)
+            );
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            SshAccessInfo sshAccessInfo = SshAccessInfo.valueOf(strSshAccessInfo);
+            check(Objects.nonNull(sshAccessInfo), "Invalid ssh access info " + context.data());
+
+            NetworkAddress vtepIp = NetworkAddress.valueOf(strVtepIp);
+            check(Objects.nonNull(vtepIp), "Invalid vtep ip " + context.data());
+
+            SshUtil.exec(sshAccessInfo,
+                    session -> {
+                        SshUtil.addIpAddrOnInterface(session, BRIDGE_UNDERLAY, vtepIp);
+                        SshUtil.setIpLinkUpOnInterface(session, BRIDGE_UNDERLAY);
+                        return "";
+                    });
+
+            context.completed();
+        }
+    }
+
+    /**
+     * Work-let class for deleting overlay bridge config.
+     */
+    public static class DeleteOverlayBridgeConfig extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+
+            Collection<BridgeDescription> bridges = bridgeConfig.getBridges();
+            return bridges.stream()
+                    .anyMatch(bd -> Objects.equals(bd.name(), BRIDGE_OVERLAY));
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+
+            bridgeConfig.deleteBridge(BridgeName.bridgeName(BRIDGE_OVERLAY));
+
+            for (int i = 0; i < 10; i++) {
+                if (!isNext(context)) {
+                    context.completed();
+                    return;
+                }
+                sleep(50);
+            }
+            throw new WorkflowException("Timeout happened for removing config");
+        }
+
+        protected void sleep(long ms) {
+            try {
+                Thread.sleep(ms);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Work-let class for removing overlay bridge openflow device.
+     */
+    public static class RemoveOverlayBridgeOfDevice extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_OVERLAY);
+
+            Device dev = context.getService(DeviceService.class).getDevice(devId);
+            return dev != null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_OVERLAY);
+
+            DeviceAdminService adminService = context.getService(DeviceAdminService.class);
+
+            context.waitCompletion(DeviceEvent.class, devId.toString(),
+                    () -> adminService.removeDevice(devId),
+                    TIMEOUT_DEVICE_CREATION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            switch (deviceEvent.type()) {
+                case DEVICE_REMOVED:
+                    return !isNext(context);
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+
+    /**
+     * Work-let class for deleting underlay bridge config.
+     */
+    public static class DeleteUnderlayBridgeConfig extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+
+            Collection<BridgeDescription> bridges = bridgeConfig.getBridges();
+            return bridges.stream()
+                    .anyMatch(bd -> Objects.equals(bd.name(), BRIDGE_UNDERLAY));
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            BridgeConfig bridgeConfig = OvsUtil.getOvsdbBehaviour(context, strMgmtIp, BridgeConfig.class);
+
+            bridgeConfig.deleteBridge(BridgeName.bridgeName(BRIDGE_UNDERLAY));
+
+            for (int i = 0; i < 10; i++) {
+                if (!isNext(context)) {
+                    context.completed();
+                    return;
+                }
+                sleep(50);
+            }
+            throw new WorkflowException("Timeout happened for removing config");
+        }
+
+        protected void sleep(long ms) {
+            try {
+                Thread.sleep(ms);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Work-let class for removing underlay bridge openflow device.
+     */
+    public static class RemoveUnderlayBridgeOfDevice extends AbstractWorklet {
+
+        @JsonDataModel(path = MODEL_MGMT_IP)
+        String strMgmtIp;
+
+        @Override
+        public boolean isNext(WorkflowContext context) throws WorkflowException {
+
+            DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_UNDERLAY_NOVA);
+
+            Device dev = context.getService(DeviceService.class).getDevice(devId);
+            return dev != null;
+        }
+
+        @Override
+        public void process(WorkflowContext context) throws WorkflowException {
+
+            DeviceId devId = OvsUtil.buildOfDeviceId(IpAddress.valueOf(strMgmtIp), DEVID_IDX_BRIDGE_UNDERLAY_NOVA);
+
+            DeviceAdminService adminService = context.getService(DeviceAdminService.class);
+
+            context.waitCompletion(DeviceEvent.class, devId.toString(),
+                    () -> adminService.removeDevice(devId),
+                    TIMEOUT_DEVICE_CREATION_MS
+            );
+        }
+
+        @Override
+        public boolean isCompleted(WorkflowContext context, Event event)throws WorkflowException {
+            if (!(event instanceof DeviceEvent)) {
+                return false;
+            }
+            DeviceEvent deviceEvent = (DeviceEvent) event;
+            switch (deviceEvent.type()) {
+                case DEVICE_REMOVED:
+                    return !isNext(context);
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void timeout(WorkflowContext context) throws WorkflowException {
+            if (!isNext(context)) {
+                context.completed(); //Complete the job of worklet by timeout
+            } else {
+                super.timeout(context);
+            }
+        }
+    }
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/package-info.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/package-info.java
new file mode 100644
index 0000000..42214bc
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Open-flow overlay implementation package.
+ */
+package org.onosproject.ofoverlay.impl;
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/NetworkAddress.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/NetworkAddress.java
new file mode 100644
index 0000000..c8a8829
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/NetworkAddress.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ofoverlay.impl.util;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Representation of a network address, which consists of IP address and prefix.
+ */
+public final class NetworkAddress {
+    private final IpAddress ip;
+    private final IpPrefix prefix;
+
+    /**
+     * Constructor for a given IP address and prefix.
+     *
+     * @param ip ip address
+     * @param prefix ip prefix
+     */
+    private NetworkAddress(IpAddress ip, IpPrefix prefix) {
+        this.ip = ip;
+        this.prefix = prefix;
+    }
+
+    /**
+     * Converts a CIDR notation string into a network address.
+     *
+     * @param cidr cidr
+     * @return network address
+     * @throws IllegalArgumentException if the cidr is not valid
+     */
+    public static NetworkAddress valueOf(String cidr) {
+        checkArgument(cidr.contains("/"));
+
+        IpAddress ipAddress = IpAddress.valueOf(cidr.split("/")[0]);
+        IpPrefix ipPrefix = IpPrefix.valueOf(cidr);
+
+        return new NetworkAddress(ipAddress, ipPrefix);
+    }
+
+    /**
+     * Returns the IP address value of the network address.
+     *
+     * @return ip address
+     */
+    public IpAddress ip() {
+        return this.ip;
+    }
+
+    /**
+     * Returns the IP prefix value of the network address.
+     *
+     * @return ip prefix
+     */
+    public IpPrefix prefix() {
+        return this.prefix;
+    }
+
+    /**
+     * Converts a network address to a CIDR notation.
+     *
+     * @return cidr notation string
+     */
+    public String cidr() {
+        return ip.toString() + "/" + prefix.prefixLength();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof NetworkAddress) {
+            NetworkAddress that = (NetworkAddress) obj;
+            return Objects.equals(ip, that.ip) && Objects.equals(prefix, that.prefix);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ip, prefix);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("IpAddress", ip)
+                .add("IpPrefix", prefix)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsDatapathType.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsDatapathType.java
new file mode 100644
index 0000000..0a64e93
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsDatapathType.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ofoverlay.impl.util;
+
+/**
+ * Enumeration for OVS data path type.
+ */
+public enum OvsDatapathType {
+    EMPTY(""),
+    NETDEV("netdev"),
+    SYSTEM("system");
+
+    private final String value;
+
+    /**
+     * Constructor for OvsDatapathType enumeration.
+     *
+     * @param value string OvsDatapathType
+     */
+    OvsDatapathType(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return value;
+    }
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsVersion.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsVersion.java
new file mode 100644
index 0000000..015ac73
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/OvsVersion.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ofoverlay.impl.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Class for OVS Version.
+ */
+public final class OvsVersion {
+    protected static final Logger log = LoggerFactory.getLogger(OvsVersion.class);
+
+    private int[] versionElements = new int[] {0, 0, 0, Integer.MAX_VALUE};
+    private int depth = 0;
+
+    /**
+     * Constructor for OvsVersion.
+     * @param ovsVerStr OVS version string
+     */
+    private OvsVersion(String ovsVerStr) {
+
+        // Supporting
+        // 1.2.3 (depth = 3, public release)
+        // 1.2.3.4 (depth = 4, beta release)
+        Matcher m = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(\\.(\\d+))?").matcher(ovsVerStr);
+
+        if (!m.matches()) {
+            throw new IllegalArgumentException("Malformed OVS version");
+        }
+
+        versionElements[0] = Integer.parseInt(m.group(1));
+        versionElements[1] = Integer.parseInt(m.group(2));
+        versionElements[2] = Integer.parseInt(m.group(3));
+
+        if (m.group(4) == null) {
+            depth = 3;
+            return;
+        }
+
+        versionElements[3] = Integer.parseInt(m.group(5));
+        depth = 4;
+    }
+
+    /**
+     * Builder for OvsVersion.
+     * @param ovsVersionStr OVS version string
+     * @return ovs version
+     */
+    public static OvsVersion build(String ovsVersionStr) {
+        try {
+            return new OvsVersion(ovsVersionStr);
+        } catch (IllegalArgumentException e) {
+            log.error("Exception Occurred {}", e);
+            return null;
+        }
+    }
+
+    private int get(int level) {
+        return versionElements[level];
+    }
+
+    private int compare(OvsVersion tgt) {
+        //Comparison example
+        // 2.7.0 < 2.7.2
+        // 2.7.0 > 2.6.9.12
+        // 2.7.0 > 2.7.0.0 (because 2.7.0 is public release)
+        for (int i = 0; i < versionElements.length; i++) {
+            if (versionElements[i] == tgt.get(i)) {
+                continue;
+            } else if (versionElements[i] < tgt.get(i)) {
+                return (i + 1) * -1;
+            } else {
+                return (i + 1);
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Returns whether this OVS version is equal to the target OVS version.
+     * @param tgt taret OVS version
+     * @return whether this OVS version is equal to the target OVS version
+     */
+    public boolean isEqOf(OvsVersion tgt) {
+        return (compare(tgt) == 0);
+    }
+
+    /**
+     * Returns whether this OVS version is prior to the target OVS version.
+     * @param tgt taret OVS version
+     * @return whether this OVS version is prior to the target OVS version
+     */
+    public boolean isPriorOf(OvsVersion tgt) {
+        return (compare(tgt) < 0);
+    }
+
+    /**
+     * Returns whether this OVS version is prior or equal to the target OVS version.
+     * @param tgt taret OVS version
+     * @return whether this OVS version is prior or equal to the target OVS version
+     */
+    public boolean isPriorOrEqOf(OvsVersion tgt) {
+        return (compare(tgt) <= 0);
+    }
+
+    /**
+     * Returns whether this OVS version is later to the target OVS version.
+     * @param tgt taret OVS version
+     * @return whether this OVS version is later to the target OVS version
+     */
+    public boolean isLaterOf(OvsVersion tgt) {
+        return (compare(tgt) > 0);
+    }
+
+    /**
+     * Returns whether this OVS version is later or equal to the target OVS version.
+     * @param tgt taret OVS version
+     * @return whether this OVS version is later or equal to the target OVS version
+     */
+    public boolean isLaterOrEqOf(OvsVersion tgt) {
+        return (compare(tgt) >= 0);
+    }
+
+    @Override
+    public String toString() {
+
+        StringBuilder strbuild = new StringBuilder();
+        strbuild.append(versionElements[0]);
+
+        for (int i = 1; i < depth; i++) {
+            strbuild.append(".");
+            strbuild.append(versionElements[i]);
+        }
+        return strbuild.toString();
+    }
+
+}
\ No newline at end of file
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshBehavior.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshBehavior.java
new file mode 100644
index 0000000..6189837
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshBehavior.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ofoverlay.impl.util;
+
+import com.jcraft.jsch.Session;
+import org.onosproject.workflow.api.WorkflowException;
+
+/**
+ * Functional interface for ssh behavior.
+ * @param <R> return value of ssh behavior
+ */
+@FunctionalInterface
+public interface SshBehavior<R> {
+
+    R apply(Session session) throws WorkflowException;
+
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshUtil.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshUtil.java
new file mode 100644
index 0000000..0c6caff
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshUtil.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ofoverlay.impl.util;
+
+import com.google.common.io.CharStreams;
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import org.onlab.packet.IpAddress;
+import org.onosproject.workflow.api.WorkflowException;
+import org.onosproject.workflow.model.accessinfo.SshAccessInfo;
+import org.slf4j.Logger;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import static org.onosproject.workflow.api.CheckCondition.check;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Class for SSH utilities.
+ */
+public final class SshUtil {
+
+    protected static final Logger log = getLogger(SshUtil.class);
+
+    private static final String STRICT_HOST_CHECKING = "StrictHostKeyChecking";
+    private static final String DEFAULT_STRICT_HOST_CHECKING = "no";
+    private static final int DEFAULT_SESSION_TIMEOUT = 30000; // milliseconds
+
+    private static final String SPACESEPERATOR = " ";
+
+    /**
+     * Default constructor.
+     */
+    private SshUtil() {
+    }
+
+    /**
+     * Creates a new session with a given ssh access information.
+     *
+     * @param sshInfo information to ssh to the remote server
+     * @return ssh session, or null
+     */
+    public static Session connect(SshAccessInfo sshInfo) {
+        Session session;
+
+        try {
+            JSch jsch = new JSch();
+            jsch.addIdentity(sshInfo.privateKey());
+
+            session = jsch.getSession(sshInfo.user(),
+                    sshInfo.remoteIp().toString(),
+                    sshInfo.port().toInt());
+            session.setConfig(STRICT_HOST_CHECKING, DEFAULT_STRICT_HOST_CHECKING);
+            session.connect(DEFAULT_SESSION_TIMEOUT);
+
+        } catch (JSchException e) {
+            log.warn("Failed to connect to {}", sshInfo.toString(), e);
+            session = authUserPwd(sshInfo);
+        }
+        return session;
+    }
+
+    /**
+     * Creates a new session with ssh access info.
+     *
+     * @param sshInfo information to ssh to the remote server
+     * @return ssh session, or null
+     */
+    public static Session authUserPwd(SshAccessInfo sshInfo) {
+        log.info("Retrying Session with {}", sshInfo);
+        try {
+            JSch jsch = new JSch();
+
+            Session session = jsch.getSession(sshInfo.user(),
+                    sshInfo.remoteIp().toString(),
+                    sshInfo.port().toInt());
+            session.setPassword(sshInfo.password());
+            session.setConfig(STRICT_HOST_CHECKING, DEFAULT_STRICT_HOST_CHECKING);
+            session.connect(DEFAULT_SESSION_TIMEOUT);
+
+            return session;
+        } catch (JSchException e) {
+            log.warn("Failed to connect to {} due to {}", sshInfo.toString(), e);
+            return null;
+        }
+    }
+
+    /**
+     * Closes a connection.
+     *
+     * @param session session ssh session
+     */
+    public static void disconnect(Session session) {
+        if (session.isConnected()) {
+            session.disconnect();
+        }
+    }
+
+    /**
+     * Fetches last term after executing command.
+     * @param session  ssh session
+     * @param command command to execute
+     * @return last term, or null
+     */
+    public static String fetchLastTerm(Session session, String command) {
+         if (session == null || !session.isConnected()) {
+             log.error("Invalid session({})", session);
+             return null;
+         }
+
+         log.info("fetchLastTerm: ssh command {} to {}", command, session.getHost());
+
+         try {
+             Channel channel = session.openChannel("exec");
+             if (channel == null) {
+                 log.error("Invalid channel of session({}) for command({})", session, command);
+                 return null;
+             }
+
+             ((ChannelExec) channel).setCommand(command);
+             channel.setInputStream(null);
+             InputStream output = channel.getInputStream();
+             channel.connect();
+             String[] lineList = null;
+
+             try (BufferedReader reader = new BufferedReader(new InputStreamReader(output, StandardCharsets.UTF_8))) {
+                 lineList = reader.lines().findFirst().get().split(SPACESEPERATOR);
+             } catch (IOException e) {
+                 log.error("Exception in fetchLastTerm", e);
+             } finally {
+                 channel.disconnect();
+                 output.close();
+             }
+
+             if (lineList.length > 0) {
+                 return lineList[lineList.length - 1];
+             } else {
+                 return null;
+             }
+
+         } catch (JSchException | IOException e) {
+             log.error("Exception in fetchLastTerm", e);
+             return null;
+         }
+    }
+
+    /**
+     * Executes a given command. It opens exec channel for the command and closes
+     * the channel when it's done.
+     *
+     * @param session ssh connection to a remote server
+     * @param command command to execute
+     * @return command output string if the command succeeds, or null
+     */
+    public static String executeCommand(Session session, String command) {
+        if (session == null || !session.isConnected()) {
+            log.error("Invalid session({})", session);
+            return null;
+        }
+
+        log.info("executeCommand: ssh command {} to {}", command, session.getHost());
+
+        try {
+            Channel channel = session.openChannel("exec");
+
+            if (channel == null) {
+                log.debug("Invalid channel of session({}) for command({})", session, command);
+                return null;
+            }
+
+            ((ChannelExec) channel).setCommand(command);
+            channel.setInputStream(null);
+            InputStream output = channel.getInputStream();
+
+            channel.connect();
+            String result = CharStreams.toString(new InputStreamReader(output, StandardCharsets.UTF_8));
+            log.trace("SSH result(on {}): {}", session.getHost(), result);
+            channel.disconnect();
+
+            return result;
+        } catch (JSchException | IOException e) {
+            log.debug("Failed to execute command {} due to {}", command, e);
+            return null;
+        }
+    }
+
+    /**
+     * Fetches OVS version information.
+     * @param session Jsch session
+     * @return OVS version
+     * @throws WorkflowException workflow exception
+     */
+    public static OvsVersion fetchOvsVersion(Session session) throws WorkflowException {
+
+        OvsVersion devOvsVersion;
+
+        String ovsVersionStr = fetchLastTerm(session, "ovs-vswitchd --version");
+        if (ovsVersionStr == null) {
+            log.error("Failed to get ovs Version String for ssh session:{}", session);
+            throw new WorkflowException("Failed to get ovs Version String");
+        }
+
+        devOvsVersion = OvsVersion.build(ovsVersionStr);
+        if (devOvsVersion == null) {
+            log.error("Failed to build OVS version for {}", ovsVersionStr);
+            throw new WorkflowException("Failed to build OVS version");
+        }
+
+        return devOvsVersion;
+    }
+
+    private static final String IP_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
+            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
+            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
+            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
+
+    private static boolean isIPv6(String address) {
+        boolean isCorrect = true;
+        try {
+            IpAddress.valueOf(address);
+        } catch (IllegalArgumentException e) {
+            log.debug("Exception Occurred {}", e.toString());
+            isCorrect = false;
+        }
+        return isCorrect;
+    }
+
+    private static boolean isCidr(String s) {
+        String[] splits = s.split("/");
+        return splits.length == 2 &&
+                (splits[0].matches(IP_PATTERN) || isIPv6(splits[0]));
+    }
+
+    /**
+     * Adds IP address on the interface.
+     * @param session SSH session
+     * @param ifname interface name
+     * @param address network address
+     * @throws WorkflowException workflow exception
+     */
+    public static void addIpAddrOnInterface(Session session, String ifname, NetworkAddress address)
+            throws WorkflowException {
+
+        executeCommand(session, String.format("ip addr add %s dev %s", address.cidr(), ifname));
+
+        Set<NetworkAddress> result = getIpAddrOfInterface(session, ifname);
+        if (!result.contains(address)) {
+            throw new WorkflowException("Failed to set ip(" + address + ") on " + ifname + ",  result: " + result);
+        }
+    }
+
+    /**
+     * Gets IP addresses of interface.
+     * @param session SSH session
+     * @param ifname interface name
+     * @return IP addresses of interface
+     */
+    public static Set<NetworkAddress> getIpAddrOfInterface(Session session, String ifname) {
+
+        String output = executeCommand(session, String.format("ip addr show %s", ifname));
+
+        if (output == null) {
+            return Collections.emptySet();
+        }
+
+        Set<NetworkAddress> result = Pattern.compile(" ")
+                .splitAsStream(output)
+                .filter(SshUtil::isCidr)
+                .map(NetworkAddress::valueOf)
+                .collect(Collectors.toSet());
+        return result;
+    }
+
+    /**
+     * Returns whether the interface has IP address.
+     * @param session SSH session
+     * @param ifname interface name
+     * @param addr network address
+     * @return whether the interface has IP address
+     */
+    public static boolean hasIpAddrOnInterface(Session session, String ifname, NetworkAddress addr) {
+
+        Set<NetworkAddress> phyBrIps = getIpAddrOfInterface(session, ifname);
+
+        return phyBrIps.stream()
+                .anyMatch(ip -> addr.ip().equals(ip.ip()));
+    }
+
+    /**
+     * Sets IP link UP on the interface.
+     * @param session SSH session
+     * @param ifname interface name
+     * @throws WorkflowException workflow exception
+     */
+    public static void setIpLinkUpOnInterface(Session session, String ifname)
+            throws WorkflowException {
+
+        executeCommand(session, String.format("ip link set %s up", ifname));
+
+        if (!isIpLinkUpOnInterface(session, ifname)) {
+            throw new WorkflowException("Failed to set UP on " + ifname);
+        }
+    }
+
+    /**
+     * Returns whether the link of the interface is up.
+     * @param session SSH session
+     * @param ifname interface name
+     * @return whether the link of the interface is up
+     */
+    public static boolean isIpLinkUpOnInterface(Session session, String ifname) {
+        String output = executeCommand(session, String.format("ip link show %s", ifname));
+
+        return output != null && output.contains("UP");
+    }
+
+    /**
+     * Executes SSH behavior.
+     * @param sshAccessInfo SSH Access information
+     * @param behavior SSH behavior
+     * @param <R> Return type of SSH behavior
+     * @return return of SSH behavior
+     * @throws WorkflowException workflow exception
+     */
+    public static <R> R exec(SshAccessInfo sshAccessInfo, SshBehavior<R> behavior)
+            throws WorkflowException {
+
+        check(sshAccessInfo != null, "Invalid sshAccessInfo");
+        Session session = connect(sshAccessInfo);
+        if (session == null || !session.isConnected()) {
+            log.error("Failed to get session for ssh:{}", sshAccessInfo);
+            throw new WorkflowException("Failed to get session for ssh:" + sshAccessInfo);
+        }
+
+        try {
+            return behavior.apply(session);
+        } finally {
+            disconnect(session);
+        }
+    }
+
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshkeyExchange.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshkeyExchange.java
new file mode 100644
index 0000000..5615112
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/SshkeyExchange.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ofoverlay.impl.util;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.KeyPair;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.SftpATTRS;
+import com.jcraft.jsch.SftpException;
+import org.onlab.packet.IpAddress;
+import org.slf4j.Logger;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Class for SSH key exchange.
+ */
+public class SshkeyExchange {
+
+    protected static final Logger log = getLogger(SshkeyExchange.class);
+    private static final String HOME_ENV = System.getProperty("user.home");
+    private static final String USER_ENV = System.getProperty("user.name");
+    private static final String PUBLIC_KEY = "/.ssh/id_rsa.pub";
+    private static final String PRIVATE_KEY = "/.ssh/id_rsa";
+    private static final String SFTP_CHANNEL = "sftp";
+    private static final String SSH_HOME = "/.ssh/";
+    private static final String SSH_AUTH_KEY = "/.ssh/authorized_keys";
+    private static final int SFTPPORT = 22;
+    private static final int DIR_PER = 448;
+    private static final int FILE_PER = 384;
+    private static final int KEY_SIZE = 2048;
+    private static final int DEFAULT_SESSION_TIMEOUT = 30000; // milliseconds
+
+    private Session getJschSession(String user, String host, String password) {
+        java.util.Properties config = new java.util.Properties();
+        config.put("StrictHostKeyChecking", "no");
+        Session session;
+        try {
+            session = new JSch().getSession(user, host, SFTPPORT);
+            session.setPassword(password);
+            session.setConfig(config);
+        } catch (JSchException e) {
+            log.error("Exception in getJschSession", e);
+            return null;
+        }
+
+        return session;
+    }
+
+    private boolean generateKeyPair() {
+        KeyPair kpair;
+        StringBuilder command = new StringBuilder()
+                .append("chmod 600 ")
+                .append(HOME_ENV)
+                .append(PRIVATE_KEY);
+        try {
+            kpair = KeyPair.genKeyPair(new JSch(), KeyPair.RSA, KEY_SIZE);
+            kpair.writePrivateKey(HOME_ENV + PRIVATE_KEY);
+            kpair.writePublicKey(HOME_ENV + PUBLIC_KEY, USER_ENV);
+            Runtime.getRuntime().exec(command.toString());
+            kpair.dispose();
+        } catch (JSchException | IOException e) {
+            log.error("Exception in generateKeyPair", e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Exchanges SSH key.
+     * @param host SSH server host
+     * @param user user
+     * @param password password
+     * @return SSH key exchange success or not
+     */
+    public boolean sshAutoKeyExchange(IpAddress host, String user, String password) {
+
+        Session session = getJschSession(user, host.toString(), password);
+        boolean returnFlag;
+        File publickeyPath = new File(HOME_ENV + PUBLIC_KEY);
+        if (session == null) {
+            log.error("Error While establishing SFTP connection with {}", host.toString());
+            return false;
+        }
+        Channel channel;
+        String remoteHome;
+        ChannelSftp sftp;
+        FileInputStream fis = null;
+        SftpATTRS attrs = null;
+        try {
+            session.connect(DEFAULT_SESSION_TIMEOUT);
+            channel = session.openChannel(SFTP_CHANNEL);
+            if (channel == null) {
+                log.error("SFTP channel open failed for {}", host.toString());
+                return false;
+            }
+            channel.connect();
+            sftp = (ChannelSftp) channel;
+            remoteHome = sftp.getHome();
+            // checking key pair existance
+
+            if (!publickeyPath.exists()) {
+                File dirs = new File(HOME_ENV + SSH_HOME);
+                if (!dirs.exists() && !dirs.mkdirs()) {
+                    log.error("{} not exists and unable to create ", dirs.getPath());
+                    return false;
+                } else if (!generateKeyPair()) {
+                    log.error("SSH Key pair generation failed");
+                    return false;
+                }
+            }
+
+            // checking for authenticate_keys file existance
+            fis = new FileInputStream(publickeyPath);
+            try {
+                sftp.lstat(remoteHome + SSH_HOME);
+            } catch (SftpException e) {
+                sftp.mkdir(remoteHome + SSH_HOME);
+                sftp.chmod(700, remoteHome + SSH_HOME);
+            }
+            try {
+                attrs = sftp.lstat(remoteHome + SSH_AUTH_KEY);
+            } catch (SftpException e) {
+                log.info("authorized_keys file does not exist at remote device ,"
+                        + "a new file will be created");
+            }
+
+            if (attrs != null) {
+                sftp.get(remoteHome + SSH_AUTH_KEY, HOME_ENV + "/tempauthorized_keys");
+
+                String pubKey;
+                try (Stream<String> st = Files.lines(Paths.get(HOME_ENV + PUBLIC_KEY))) {
+                    pubKey = st.collect(Collectors.joining());
+                }
+
+                String authKey;
+                try (Stream<String> st = Files.lines(Paths.get(HOME_ENV + "/tempauthorized_keys"))) {
+                    authKey = st.collect(Collectors.joining());
+                }
+
+                if (authKey.contains(pubKey)) {
+                    log.info("Skipping key append to server as Key is already added");
+                } else {
+                    sftp.put(fis, remoteHome + SSH_AUTH_KEY, ChannelSftp.APPEND);
+                    log.info("Public key appended to server");
+                }
+            } else {
+
+                sftp.put(fis, remoteHome + SSH_AUTH_KEY, ChannelSftp.APPEND);
+                // Give proper permission to file and directory.
+                sftp.chmod(DIR_PER, remoteHome + SSH_HOME);
+                sftp.chmod(FILE_PER, remoteHome + SSH_AUTH_KEY);
+                log.info("Public key appended to server");
+            }
+
+            sftp.exit();
+            session.disconnect();
+            returnFlag = true;
+        } catch (JSchException | SftpException | IOException e) {
+            log.error("Exception occured because of {} ", e);
+            returnFlag = false;
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                    log.info("Error closing public key file");
+                }
+            }
+        }
+        return returnFlag;
+
+    }
+}
diff --git a/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/package-info.java b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/package-info.java
new file mode 100644
index 0000000..c76ba58
--- /dev/null
+++ b/apps/workflow/ofoverlay/app/src/main/java/org/onosproject/ofoverlay/impl/util/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Utility classes of ofoverlay.
+ */
+package org.onosproject.ofoverlay.impl.util;
\ No newline at end of file
