diff --git oak-jcr/pom.xml oak-jcr/pom.xml
index 08ebf53..32215c2 100644
--- oak-jcr/pom.xml
+++ oak-jcr/pom.xml
@@ -266,6 +266,32 @@
       <artifactId>slf4j-api</artifactId>
     </dependency>
 
+
+    <dependency>
+      <groupId>com.googlecode.pojosr</groupId>
+      <artifactId>de.kalpatec.pojosr.framework.bare</artifactId>
+      <version>0.2.1</version>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.scr</artifactId>
+      <version>1.8.2</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.configadmin</artifactId>
+      <version>1.8.0</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.fileinstall</artifactId>
+      <version>3.2.8</version>
+      <scope>runtime</scope>
+    </dependency>
+
     <!-- Findbugs annotations -->
     <dependency>
       <groupId>com.google.code.findbugs</groupId>
diff --git oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/osgi/OakOSGiRepositoryFactory.java oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/osgi/OakOSGiRepositoryFactory.java
new file mode 100644
index 0000000..a5225ed
--- /dev/null
+++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/osgi/OakOSGiRepositoryFactory.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jackrabbit.oak.jcr.osgi;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.SettableFuture;
+import de.kalpatec.pojosr.framework.launch.BundleDescriptor;
+import de.kalpatec.pojosr.framework.launch.ClasspathScanner;
+import de.kalpatec.pojosr.framework.launch.PojoServiceRegistry;
+import de.kalpatec.pojosr.framework.launch.PojoServiceRegistryFactory;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class OakOSGiRepositoryFactory implements RepositoryFactory{
+
+    private static Logger log = LoggerFactory.getLogger(OakOSGiRepositoryFactory.class);
+    /**
+     * Name of the repository home parameter.
+     */
+    public static final String REPOSITORY_HOME
+            = "org.apache.jackrabbit.repository.home";
+
+    public static final String REPOSITORY_STARTUP_TIMEOUT
+            = "org.apache.jackrabbit.repository.startupTimeOut";
+
+    /**
+     * Default timeout for repository creation
+     */
+    private static final int DEFAULT_TIMEOUT = (int) TimeUnit.MINUTES.toSeconds(10);
+
+    public Repository getRepository(Map parameters) throws RepositoryException {
+        Map config = new HashMap();
+        config.putAll(parameters);
+
+        //TODO Add support for passing config as map of PID -> Dictionary
+        //as part of parameters and hook it up with Felix ConfigAdmin
+        //Say via custom InMemory PersistenceManager or programatically
+        //registering it with using ConfigAdmin API
+        //For later part we would need to implement some sort of Start Level
+        //support such that
+        // 1. Some base bundles like ConfigAdmin get start first
+        // 2. We register the user provided config
+        // 3. Other bundles get started
+
+        processConfig(config);
+
+        PojoServiceRegistry registry = createServiceRegistry(config);
+        preProcessRegistry(registry);
+        startBundles(registry);
+        postProcessRegistry(registry);
+
+        //Future which would be used to notify when repository is ready
+        // to be used
+        SettableFuture<Repository> repoFuture = SettableFuture.create();
+
+        //Start the tracker for repository creation
+        new RepositoryTracker(registry, repoFuture);
+
+        //Now wait for repository to be created with given timeout
+        //if repository creation takes more time. This is required to handle case
+        // where OSGi runtime fails to start due to bugs (like cycles)
+        int timeout = getTimeoutInSeconds(config);
+        try {
+            return repoFuture.get(timeout, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RepositoryException("Repository initialization was interrupted");
+        } catch (ExecutionException e) {
+            throw new RepositoryException(e);
+        } catch (TimeoutException e) {
+            try {
+                shutdown(registry);
+            } catch (BundleException be) {
+                log.warn("Error occurred while shutting down the service registry (due to " +
+                        "startup timeout) backing the Repository ", be);
+            }
+            throw new RepositoryException("Repository could not be started in "+
+                    timeout+" seconds",e);
+        }
+    }
+
+    /**
+     * Enables pre processing of service registry by sub classes. This can be
+     * used to register services before any bundle gets started
+     *
+     * @param registry service registry
+     */
+    protected void preProcessRegistry(PojoServiceRegistry registry) {
+
+    }
+
+    /**
+     * Enables post processing of service registry e.g. registering new services etc
+     * by sub classes
+     *
+     * @param registry service registry
+     */
+    protected void postProcessRegistry(PojoServiceRegistry registry){
+
+    }
+
+    /**
+     *
+     * @param descriptors
+     * @return
+     */
+    protected List<BundleDescriptor> processDescriptors(List<BundleDescriptor> descriptors) {
+        //If required sort the bundle descriptors such that configuration admin and file install bundle
+        //gets started before SCR
+        return descriptors;
+    }
+
+    static void shutdown(PojoServiceRegistry registry) throws BundleException{
+        if(registry != null){
+            registry.getBundleContext().getBundle().stop();
+        }
+    }
+
+    private static int getTimeoutInSeconds(Map config) {
+        Integer timeout = (Integer) config.get(REPOSITORY_STARTUP_TIMEOUT);
+        if(timeout == null){
+            timeout = DEFAULT_TIMEOUT;
+        }
+        return timeout;
+    }
+
+    private static void processConfig(Map config) {
+        String home = (String) config.get(REPOSITORY_HOME);
+        checkNotNull(home, "Repository home not defined via [%s]", REPOSITORY_HOME);
+
+        home = FilenameUtils.normalizeNoEndSeparator(home);
+
+        String bundleDir = FilenameUtils.concat(home, "bundles");
+        config.put(Constants.FRAMEWORK_STORAGE, bundleDir);
+
+        //FIXME Pojo SR currently reads this from system property instead of Framework Property
+        System.setProperty(Constants.FRAMEWORK_STORAGE, bundleDir);
+
+        //Directory used by Felix File Install to watch for configs
+        config.put("felix.fileinstall.dir", FilenameUtils.concat(home, "config"));
+        config.put("felix.fileinstall.log.level", 4);
+
+        //Directory used by Felix File Install to watch for configs
+        config.put("repository.home", FilenameUtils.concat(home, "repository"));
+
+        copyConfigToSystemProps(config);
+    }
+
+    private static void copyConfigToSystemProps(Map config) {
+        //TODO This is a temporary workaround as the current release version
+        //of PojoSR reads value from System properties. Trunk version reads from
+        //initial map. This should be removed when we move to version which has the fix
+        Iterator<Map.Entry> itr = config.entrySet().iterator();
+        while(itr.hasNext()){
+            Map.Entry e = itr.next();
+            if(e.getValue() instanceof String){
+                System.setProperty((String)e.getKey(), (String)e.getValue());
+            }
+        }
+    }
+
+    private PojoServiceRegistry createServiceRegistry(Map<String,Object> config) {
+        try {
+            ServiceLoader<PojoServiceRegistryFactory> loader = ServiceLoader.load(PojoServiceRegistryFactory.class);
+            return loader.iterator().next().newPojoServiceRegistry(config);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    private void startBundles(PojoServiceRegistry registry){
+        try{
+            List<BundleDescriptor> descriptors = new ClasspathScanner().scanForBundles();
+            descriptors = processDescriptors(descriptors);
+            registry.startBundles(descriptors);
+        }catch(Exception e){
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static class RepositoryTracker extends ServiceTracker {
+        private final SettableFuture<Repository> repoFuture;
+        private final PojoServiceRegistry registry;
+        private RepositoryProxy proxy;
+
+        public RepositoryTracker(PojoServiceRegistry registry, SettableFuture<Repository> repoFuture) {
+            super(registry.getBundleContext(), Repository.class.getName(), null);
+            this.repoFuture = repoFuture;
+            this.registry = registry;
+            this.open();
+        }
+
+        @Override
+        public Object addingService(ServiceReference reference) {
+            Object service = super.addingService(reference);
+            if(proxy == null){
+                //As its possible that future is accessed before the service
+                //get registered with tracker. We also capture the initial reference
+                //and use that for the first access case
+                repoFuture.set(createProxy((Repository) service));
+            }
+            return service;
+        }
+
+        @Override
+        public void removedService(ServiceReference reference, Object service) {
+            if(proxy != null){
+                proxy.clearInitialReference();
+            }
+        }
+
+        public PojoServiceRegistry getRegistry() {
+            return registry;
+        }
+
+        private Repository createProxy(Repository service) {
+            proxy = new RepositoryProxy(this,service);
+            return (Repository) Proxy.newProxyInstance(getClass().getClassLoader(),
+                    new Class[] {Repository.class, JackrabbitRepository.class}, proxy);
+        }
+    }
+
+    /**
+     * Due to the way SecurityConfiguration is managed in OSGi env its possible
+     * that repository gets created/shutdown few times. So need to have a proxy
+     * to access the latest service
+     */
+    private static class RepositoryProxy implements InvocationHandler {
+        private final RepositoryTracker tracker;
+        private Repository initialService;
+
+        private RepositoryProxy(RepositoryTracker tracker, Repository initialService) {
+            this.tracker = tracker;
+            this.initialService = initialService;
+        }
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            Object obj = tracker.getService();
+            if(obj == null){
+                obj = initialService;
+            }
+
+            Preconditions.checkNotNull(obj, "Repository service is not available");
+
+            if("shutdown".equals(method.getName())){
+                shutdown(tracker.getRegistry());
+            }
+
+            return method.invoke(obj, args);
+        }
+
+        public void clearInitialReference(){
+            this.initialService = null;
+        }
+    }
+}
diff --git oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/osgi/OakOSGiRepositoryFactoryTest.java oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/osgi/OakOSGiRepositoryFactoryTest.java
new file mode 100644
index 0000000..a2a0ccb
--- /dev/null
+++ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/osgi/OakOSGiRepositoryFactoryTest.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jackrabbit.oak.jcr.osgi;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import de.kalpatec.pojosr.framework.launch.PojoServiceRegistry;
+import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.user.action.AbstractAuthorizableAction;
+import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableAction;
+import org.apache.jackrabbit.oak.spi.security.user.action.AuthorizableActionProvider;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.commons.io.FilenameUtils.concat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@Ignore
+public class OakOSGiRepositoryFactoryTest {
+
+    private String repositoryHome;
+    private RepositoryFactory repositoryFactory = new CustomOakFactory();
+    private Map config = new HashMap();
+    private String newPassword;
+
+    @Before
+    public void setUp() throws IOException {
+        repositoryHome = concat(getBaseDir(), "target/repository");
+        config.put("org.apache.jackrabbit.repository.home", repositoryHome);
+
+        File repoHome = new File(repositoryHome);
+        if(repoHome.exists()){
+            FileUtils.cleanDirectory(new File(repositoryHome));
+        }
+//        copyConfig("common");
+    }
+
+    @Test
+    public void testRepositoryTar() throws Exception {
+//        copyConfig("tar");
+
+        Repository repository = repositoryFactory.getRepository(config);
+
+//        //Give time for system to stablize :(
+//        TimeUnit.SECONDS.sleep(1);
+
+        assertNotNull(repository);
+        System.out.println("Repository started ");
+
+        basicCrudTest(repository);
+
+        //For now SecurityConfig is giving some issue
+        //so disable that
+        testCallback(repository);
+
+
+        shutdown(repository);
+    }
+
+    private void testCallback(Repository repository) throws RepositoryException {
+        JackrabbitSession session = (JackrabbitSession)
+                repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
+
+        String testUserId = "footest";
+
+        User testUser  = (User) session.getUserManager().getAuthorizable(testUserId);
+        if(testUser == null){
+            testUser = session.getUserManager().createUser(testUserId,"password");
+        }
+
+        session.save();
+
+        testUser.changePassword("newPassword");
+        session.save();
+
+        assertEquals("newPassword",newPassword);
+    }
+
+    private void basicCrudTest(Repository repository) throws RepositoryException {
+        Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
+        Node rootNode = session.getRootNode();
+
+        Node child  = JcrUtils.getOrAddNode(rootNode,"child", "oak:Unstructured");
+        child.setProperty("foo3",  "bar3");
+        session.logout();
+
+        System.out.println("Basic test passed");
+    }
+
+    private void shutdown(Repository repository) {
+        if(repository instanceof JackrabbitRepository){
+            ((JackrabbitRepository) repository).shutdown();
+        }
+    }
+
+    private void copyConfig(String type) throws IOException {
+        FileUtils.copyDirectory(new File(concat(getBaseDir(),"src/test/resources/config-"+type)),
+                new File(concat(repositoryHome,"config")));
+    }
+
+    private static String getBaseDir(){
+        return new File(".").getAbsolutePath();
+    }
+
+    private class CustomOakFactory extends OakOSGiRepositoryFactory {
+
+        @Override
+        protected void postProcessRegistry(PojoServiceRegistry registry) {
+            registry.registerService(AuthorizableActionProvider.class.getName(), new AuthorizableActionProvider() {
+                @Override
+                public List<? extends AuthorizableAction> getAuthorizableActions(SecurityProvider securityProvider) {
+                    return Collections.singletonList(new TestAction());
+                }
+            }, null);
+        }
+    }
+
+    private class TestAction extends AbstractAuthorizableAction {
+
+        @Override
+        public void onPasswordChange(User user, String newPassword,
+                                     Root root, NamePathMapper namePathMapper) throws RepositoryException {
+            OakOSGiRepositoryFactoryTest.this.newPassword = newPassword;
+        }
+    }
+}
