diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -27,7 +27,9 @@
   llvm::StringRef installName;
   llvm::StringRef outputFile;
   llvm::MachO::HeaderFileType outputType;
-  std::vector<llvm::StringRef> searchPaths;
+  // TODO: use the library and framework search paths
+  std::vector<llvm::StringRef> librarySearchPaths;
+  std::vector<llvm::StringRef> frameworkSearchPaths;
   llvm::DenseMap<llvm::StringRef, SymbolPriorityEntry> priorities;
 };
 
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -30,6 +30,7 @@
 #include "llvm/Object/Archive.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/Host.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 
@@ -83,7 +84,7 @@
 
 // This is for -lfoo. We'll look for libfoo.dylib from search paths.
 static Optional<std::string> findDylib(StringRef name) {
-  for (StringRef dir : config->searchPaths) {
+  for (StringRef dir : config->librarySearchPaths) {
     std::string path = (dir + "/lib" + name + ".dylib").str();
     if (fs::exists(path))
       return path;
@@ -99,13 +100,51 @@
   return createX86_64TargetInfo();
 }
 
-static std::vector<StringRef> getSearchPaths(opt::InputArgList &args) {
-  std::vector<StringRef> ret{args::getStrings(args, OPT_L)};
-  if (!args.hasArg(OPT_Z)) {
-    ret.push_back("/usr/lib");
-    ret.push_back("/usr/local/lib");
+static bool isDirectory(StringRef option, StringRef path) {
+  if (!fs::exists(path)) {
+    warn("directory not found for option -" + option + path);
+    return false;
+  } else if (!fs::is_directory(path)) {
+    warn("option -" + option + path + " references a non-directory path");
+    return false;
+  }
+  return true;
+}
+
+static std::vector<StringRef> getLibrarySearchPaths(opt::InputArgList &args,
+                                                    bool isOSDarwin) {
+  std::vector<StringRef> paths;
+  for (auto const &path : args::getStrings(args, OPT_L)) {
+    if (isDirectory("L", path))
+      paths.push_back(path);
+  }
+  if (isOSDarwin && !args.hasArg(OPT_Z)) {
+    StringRef usrLib("/usr/lib");
+    StringRef usrLocalLib("/usr/local/lib");
+    if (isDirectory("L", usrLib))
+      paths.push_back(usrLib);
+    if (isDirectory("L", usrLocalLib))
+      paths.push_back(usrLocalLib);
+  }
+  return paths;
+}
+
+static std::vector<StringRef> getFrameworkSearchPaths(opt::InputArgList &args,
+                                                      bool isOSDarwin) {
+  std::vector<StringRef> paths;
+  for (auto const &path : args::getStrings(args, OPT_F)) {
+    if (isDirectory("F", path))
+      paths.push_back(path);
+  }
+  if (isOSDarwin && !args.hasArg(OPT_Z)) {
+    StringRef libFrames("/Library/Frameworks");
+    StringRef sysLibFrames("/System/Library/Frameworks");
+    if (isDirectory("F", libFrames))
+      paths.push_back(libFrames);
+    if (isDirectory("F", sysLibFrames))
+      paths.push_back(sysLibFrames);
   }
-  return ret;
+  return paths;
 }
 
 static void addFile(StringRef path) {
@@ -378,14 +417,19 @@
   config->outputFile = args.getLastArgValue(OPT_o, "a.out");
   config->installName =
       args.getLastArgValue(OPT_install_name, config->outputFile);
-  config->searchPaths = getSearchPaths(args);
+  bool isOSDarwin = Triple(sys::getProcessTriple()).isOSDarwin();
+  config->librarySearchPaths = getLibrarySearchPaths(args, isOSDarwin);
+  config->frameworkSearchPaths = getFrameworkSearchPaths(args, isOSDarwin);
   config->outputType = args.hasArg(OPT_dylib) ? MH_DYLIB : MH_EXECUTE;
 
   if (args.hasArg(OPT_v)) {
     message(getLLDVersion());
-    std::vector<StringRef> &searchPaths = config->searchPaths;
-    message("Library search paths:\n" +
-            llvm::join(searchPaths.begin(), searchPaths.end(), "\n"));
+    message("Library search paths:" +
+            std::string(config->librarySearchPaths.size() ? "\n\t" : "") +
+            llvm::join(config->librarySearchPaths, "\n\t"));
+    message("Framework search paths:" +
+            std::string(config->frameworkSearchPaths.size() ? "\n\t" : "") +
+            llvm::join(config->frameworkSearchPaths, "\n\t"));
     freeArena();
     return !errorCount();
   }
@@ -396,6 +440,8 @@
     switch (opt.getID()) {
     case OPT_o:
     case OPT_dylib:
+    case OPT_L:
+    case OPT_F:
       // handled elsewhere ...
       break;
     default:
diff --git a/lld/test/MachO/search-paths.test b/lld/test/MachO/search-paths.test
--- a/lld/test/MachO/search-paths.test
+++ b/lld/test/MachO/search-paths.test
@@ -1,12 +1,33 @@
-RUN: mkdir -p %t
-
-RUN: lld -flavor darwinnew -v -L%t 2>&1 | FileCheck -DDIR=%t %s
-CHECK:      Library search paths:
-CHECK-NEXT: [[DIR]]
-CHECK-NEXT: /usr/lib
-CHECK-NEXT: /usr/local/lib
-
-RUN: lld -flavor darwinnew -v -L%t -Z 2>&1 | FileCheck -DDIR=%t --check-prefix=CHECK_Z %s
-CHECK_Z:      Library search paths:
-CHECK_Z-NEXT: [[DIR]]
-CHECK_Z-NOT:  /usr/
+RUN: rm -fr %t1 %t2 %t3
+RUN: mkdir -p %t1
+RUN: touch %t2
+
+RUN: not lld -flavor darwinnew -L%t1 -L%t2 -L%t3 2>&1 \
+RUN:     | FileCheck --check-prefix=CHECK_LF -DT1=%t1 -DT2=%t2 -DT3=%t3 %s
+RUN: not lld -flavor darwinnew -L %t1 -L %t2 -L %t3 2>&1 \
+RUN:     | FileCheck --check-prefix=CHECK_LF -DT1=%t1 -DT2=%t2 -DT3=%t3 %s
+RUN: not lld -flavor darwinnew -F%t1 -F%t2 -F%t3 2>&1 \
+RUN:     | FileCheck --check-prefix=CHECK_LF -DT1=%t1 -DT2=%t2 -DT3=%t3 %s
+RUN: not lld -flavor darwinnew -F %t1 -F %t2 -F %t3 2>&1 \
+RUN:     | FileCheck --check-prefix=CHECK_LF -DT1=%t1 -DT2=%t2 -DT3=%t3 %s
+
+CHECK_LF: warning: option -{{[LF]}}[[T2]] references a non-directory path
+CHECK_LF-NEXT: warning: directory not found for option -{{[LF]}}[[T3]]
+CHECK_LF-NEXT: undefined symbol: _main
+
+RUN: lld -flavor darwinnew -v -L %t1 2>&1 \
+RUN:     | FileCheck --check-prefix=CHECK_vL -DT1=%t1 %s
+
+CHECK_vL: LLD {{[0-9.]+ .*}}
+CHECK_vL-NEXT: Library search paths:
+CHECK_vL-NEXT: [[T1]]
+CHECK_vL-NEXT: Framework search paths:
+
+RUN: lld -flavor darwinnew -v -F %t1 2>&1 \
+RUN:     | FileCheck --check-prefix=CHECK_vF -DT1=%t1 %s
+
+CHECK_vF: LLD {{[0-9.]+ .*}}
+CHECK_vF-NEXT: Library search paths:
+CHECK_vF-NEXT: Framework search paths:
+CHECK_vF-NEXT: [[T1]]
+