diff --git a/apps/optical/src/main/java/org/onlab/onos/optical/cfg/OpticalConfigProvider.java b/apps/optical/src/main/java/org/onlab/onos/optical/cfg/OpticalConfigProvider.java
new file mode 100644
index 0000000..86c1c0b
--- /dev/null
+++ b/apps/optical/src/main/java/org/onlab/onos/optical/cfg/OpticalConfigProvider.java
@@ -0,0 +1,338 @@
+package org.onlab.onos.optical.cfg;
+
+import static org.onlab.onos.net.DeviceId.deviceId;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.DefaultAnnotations;
+import org.onlab.onos.net.Device;
+import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.Link;
+import org.onlab.onos.net.MastershipRole;
+import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.device.DefaultDeviceDescription;
+import org.onlab.onos.net.device.DeviceDescription;
+import org.onlab.onos.net.device.DeviceProvider;
+import org.onlab.onos.net.device.DeviceProviderRegistry;
+import org.onlab.onos.net.device.DeviceProviderService;
+import org.onlab.onos.net.link.DefaultLinkDescription;
+import org.onlab.onos.net.link.LinkProvider;
+import org.onlab.onos.net.link.LinkProviderRegistry;
+import org.onlab.onos.net.link.LinkProviderService;
+import org.onlab.onos.net.provider.AbstractProvider;
+import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.packet.ChassisId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * OpticalConfigProvider emulates the SB network provider for optical switches,
+ * optical links and any other state that needs to be configured for correct network
+ * operations.
+ *
+ */
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+@Component(immediate = true)
+public class OpticalConfigProvider extends AbstractProvider implements DeviceProvider, LinkProvider {
+
+    protected static final Logger log = LoggerFactory
+            .getLogger(OpticalConfigProvider.class);
+
+    // TODO: fix hard coded file path later.
+    private static final String DEFAULT_CONFIG_FILE =
+            "/opt/onos/config/demo-3-roadm-2-ps.json";
+    private String configFileName = DEFAULT_CONFIG_FILE;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkProviderRegistry linkProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceProviderRegistry deviceProviderRegistry;
+
+    private static final String OPTICAL_ANNOTATION = "optical.";
+
+    private LinkProviderService linkProviderService;
+    private DeviceProviderService deviceProviderService;
+
+    private static final List<Roadm> RAW_ROADMS = new ArrayList<>();
+    private static final List<WdmLink> RAW_WDMLINKS = new ArrayList<>();
+    private static final List<PktOptLink> RAW_PKTOPTLINKS = new ArrayList<>();
+
+    private static final String ROADM = "Roadm";
+    private static final String WDM_LINK = "wdmLink";
+    private static final String PKT_OPT_LINK = "pktOptLink";
+
+    protected OpticalNetworkConfig opticalNetworkConfig;
+
+    public OpticalConfigProvider() {
+        super(new ProviderId("of", "org.onlab.onos.provider.opticalConfig", true));
+    }
+
+    @Activate
+    protected void activate() {
+        linkProviderService = linkProviderRegistry.register(this);
+        deviceProviderService = deviceProviderRegistry.register(this);
+        log.info("Starting optical network configuration process...");
+        log.info("Optical config file set to {}", configFileName);
+
+        loadOpticalConfig();
+        parseOpticalConfig();
+        publishOpticalConfig();
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        linkProviderRegistry.unregister(this);
+        linkProviderService = null;
+        deviceProviderRegistry.unregister(this);
+        deviceProviderService = null;
+        RAW_ROADMS.clear();
+        RAW_WDMLINKS.clear();
+        RAW_PKTOPTLINKS.clear();
+        log.info("Stopped");
+    }
+
+    private void loadOpticalConfig() {
+        ObjectMapper mapper = new ObjectMapper();
+        opticalNetworkConfig = new OpticalNetworkConfig();
+        try {
+            opticalNetworkConfig = mapper.readValue(new File(configFileName), OpticalNetworkConfig.class);
+        } catch (JsonParseException e) {
+            String err = String.format("JsonParseException while loading network "
+                    + "config from file: %s: %s", configFileName, e.getMessage());
+            log.error(err, e);
+        } catch (JsonMappingException e) {
+            String err = String.format(
+                    "JsonMappingException while loading network config "
+                            + "from file: %s: %s", configFileName, e.getMessage());
+            log.error(err, e);
+        } catch (IOException e) {
+            String err = String.format("IOException while loading network config "
+                    + "from file: %s %s", configFileName, e.getMessage());
+            log.error(err, e);
+        }
+    }
+
+    private void parseOpticalConfig() {
+        List<OpticalSwitchDescription> swList = opticalNetworkConfig.getOpticalSwitches();
+        List<OpticalLinkDescription> lkList = opticalNetworkConfig.getOpticalLinks();
+
+        for (OpticalSwitchDescription sw : swList) {
+            String swtype = sw.getType();
+            boolean allow = sw.isAllowed();
+           if (swtype.equals(ROADM) && allow) {
+               int regNum = 0;
+               Set<Map.Entry<String, JsonNode>> m = sw.params.entrySet();
+               for (Map.Entry<String, JsonNode> e : m) {
+                       String key = e.getKey();
+                       JsonNode j = e.getValue();
+                       if (key.equals("numRegen")) {
+                           regNum = j.asInt();
+                       }
+                }
+
+                Roadm newRoadm = new Roadm();
+                newRoadm.setName(sw.name);
+                newRoadm.setNodeId(sw.nodeDpid);
+                newRoadm.setLongtitude(sw.longitude);
+                newRoadm.setLatitude(sw.latitude);
+                newRoadm.setRegenNum(regNum);
+
+                RAW_ROADMS.add(newRoadm);
+                log.info(newRoadm.toString());
+            }
+           }
+
+        for (OpticalLinkDescription lk : lkList) {
+            String lktype = lk.getType();
+            switch (lktype) {
+            case WDM_LINK:
+                WdmLink newWdmLink = new WdmLink();
+                newWdmLink.setSrcNodeId(lk.getNodeDpid1());
+                newWdmLink.setSnkNodeId(lk.getNodeDpid2());
+                newWdmLink.setAdminWeight(1000); // default weight for each WDM link.
+                Set<Map.Entry<String, JsonNode>> m = lk.params.entrySet();
+                for (Map.Entry<String, JsonNode> e : m) {
+                    String key = e.getKey();
+                    JsonNode j = e.getValue();
+                    if (key.equals("nodeName1")) {
+                        newWdmLink.setSrcNodeName(j.asText());
+                    } else if (key.equals("nodeName2")) {
+                        newWdmLink.setSnkNodeName(j.asText());
+                    } else if (key.equals("port1")) {
+                        newWdmLink.setSrcPort(j.asInt());
+                    } else if (key.equals("port2")) {
+                        newWdmLink.setSnkPort(j.asInt());
+                    } else if (key.equals("distKms")) {
+                        newWdmLink.setDistance(j.asDouble());
+                    } else if (key.equals("numWaves")) {
+                        newWdmLink.setWavelengthNumber(j.asInt());
+                    } else {
+                        log.error("error found");
+                        // TODO add exception processing;
+                    }
+                }
+                RAW_WDMLINKS.add(newWdmLink);
+                log.info(newWdmLink.toString());
+
+                break;
+
+            case PKT_OPT_LINK:
+                PktOptLink newPktOptLink = new PktOptLink();
+                newPktOptLink.setSrcNodeId(lk.getNodeDpid1());
+                newPktOptLink.setSnkNodeId(lk.getNodeDpid2());
+                newPktOptLink.setAdminWeight(10); // default weight for each packet-optical link.
+                Set<Map.Entry<String, JsonNode>> ptm = lk.params.entrySet();
+                for (Map.Entry<String, JsonNode> e : ptm) {
+                    String key = e.getKey();
+                    JsonNode j = e.getValue();
+                    if (key.equals("nodeName1")) {
+                        newPktOptLink.setSrcNodeName(j.asText());
+                    } else if (key.equals("nodeName2")) {
+                        newPktOptLink.setSnkNodeName(j.asText());
+                    } else if (key.equals("port1")) {
+                        newPktOptLink.setSrcPort(j.asInt());
+                    } else if (key.equals("port2")) {
+                        newPktOptLink.setSnkPort(j.asInt());
+                    } else if (key.equals("bandWidth")) {
+                        newPktOptLink.setBandwdith(j.asDouble());
+                    } else {
+                        log.error("error found");
+                        // TODO add exception processing;
+                    }
+                }
+
+                RAW_PKTOPTLINKS.add(newPktOptLink);
+                log.info(newPktOptLink.toString());
+                break;
+            default:
+            }
+        }
+    }
+
+    private void publishOpticalConfig() {
+        if (deviceProviderService == null || linkProviderService == null) {
+            return;
+        }
+
+        // Discover the optical ROADM objects
+        Iterator<Roadm> iterWdmNode = RAW_ROADMS.iterator();
+        while (iterWdmNode.hasNext()) {
+            Roadm value = iterWdmNode.next();
+            DeviceId did = deviceId("of:" + value.getNodeId().replace(":", ""));
+            ChassisId cid = new ChassisId(value.getNodeId());
+            DefaultAnnotations extendedAttributes = DefaultAnnotations.builder()
+                    .set(OPTICAL_ANNOTATION + "switchType", "ROADM")
+                    .set(OPTICAL_ANNOTATION + "switchName", value.getName())
+                    .set(OPTICAL_ANNOTATION + "latitude", Double.toString(value.getLatitude()))
+                    .set(OPTICAL_ANNOTATION + "longtitude", Double.toString(value.getLongtitude()))
+                    .set(OPTICAL_ANNOTATION + "regNum", Integer.toString(value.getRegenNum()))
+                    .build();
+
+            DeviceDescription description =
+                    new DefaultDeviceDescription(did.uri(),
+                                                 Device.Type.SWITCH,
+                                                 "",
+                                                 "",
+                                                 "",
+                                                 "",
+                                                 cid,
+                                                 extendedAttributes);
+            deviceProviderService.deviceConnected(did, description);
+        }
+
+        // Discover the optical WDM link objects
+        Iterator<WdmLink> iterWdmlink = RAW_WDMLINKS.iterator();
+        while (iterWdmlink.hasNext()) {
+            WdmLink value = iterWdmlink.next();
+
+            DeviceId srcNodeId = deviceId("of:" + value.getSrcNodeId().replace(":", ""));
+            DeviceId snkNodeId = deviceId("of:" + value.getSnkNodeId().replace(":", ""));
+
+            PortNumber srcPort = PortNumber.portNumber(value.getSrcPort());
+            PortNumber snkPort = PortNumber.portNumber(value.getSnkPort());
+
+            ConnectPoint srcPoint = new ConnectPoint(srcNodeId, srcPort);
+            ConnectPoint snkPoint = new ConnectPoint(snkNodeId, snkPort);
+
+            DefaultAnnotations extendedAttributes = DefaultAnnotations.builder()
+                    .set(OPTICAL_ANNOTATION + "linkType", "WDM")
+                    .set(OPTICAL_ANNOTATION + "distance", Double.toString(value.getDistance()))
+                    .set(OPTICAL_ANNOTATION + "cost", Double.toString(value.getDistance()))
+                    .set(OPTICAL_ANNOTATION + "adminWeight", Double.toString(value.getAdminWeight()))
+                    .set(OPTICAL_ANNOTATION + "wavelengthNum", Integer.toString(value.getWavelengthNumber()))
+                    .build();
+
+            DefaultLinkDescription linkDescription =
+                    new DefaultLinkDescription(srcPoint,
+                                                 snkPoint,
+                                                 Link.Type.DIRECT,
+                                                 extendedAttributes);
+
+            linkProviderService.linkDetected(linkDescription);
+            log.info(String.format("WDM link: %s : %s",
+                    linkDescription.src().toString(), linkDescription.dst().toString()));
+        }
+
+        // Discover the packet optical link objects
+        Iterator<PktOptLink> iterPktOptlink = RAW_PKTOPTLINKS.iterator();
+        while (iterPktOptlink.hasNext()) {
+            PktOptLink value = iterPktOptlink.next();
+            DeviceId srcNodeId = deviceId("of:" + value.getSrcNodeId().replace(":", ""));
+            DeviceId snkNodeId = deviceId("of:" + value.getSnkNodeId().replace(":", ""));
+
+            PortNumber srcPort = PortNumber.portNumber(value.getSrcPort());
+            PortNumber snkPort = PortNumber.portNumber(value.getSnkPort());
+
+            ConnectPoint srcPoint = new ConnectPoint(srcNodeId, srcPort);
+            ConnectPoint snkPoint = new ConnectPoint(snkNodeId, snkPort);
+
+            DefaultAnnotations extendedAttributes = DefaultAnnotations.builder()
+                    .set(OPTICAL_ANNOTATION + "linkType", "PktOptLink")
+                    .set(OPTICAL_ANNOTATION + "bandwidth", Double.toString(value.getBandwidth()))
+                    .set(OPTICAL_ANNOTATION + "cost", Double.toString(value.getBandwidth()))
+                    .set(OPTICAL_ANNOTATION + "adminWeight", Double.toString(value.getAdminWeight()))
+                    .build();
+
+            DefaultLinkDescription linkDescription =
+                    new DefaultLinkDescription(srcPoint,
+                                                 snkPoint,
+                                                 Link.Type.DIRECT,
+                                                 extendedAttributes);
+
+            linkProviderService.linkDetected(linkDescription);
+            log.info(String.format("Packet-optical link: %s : %s",
+                    linkDescription.src().toString(), linkDescription.dst().toString()));
+        }
+
+    }
+
+    @Override
+    public void triggerProbe(Device device) {
+        // TODO We may want to consider re-reading config files and publishing them based on this event.
+    }
+
+    @Override
+    public void roleChanged(Device device, MastershipRole newRole) {
+        // TODO Auto-generated method stub.
+    }
+
+}
