MVVM is a band-aid for poorly designed data binding layers. In particular, it has seen a lot of use in the WPF/silverlight/WP7 world because of limitations in data binding in WPF/XAML.
From now on, I'm going to assume we're talking about WPF/XAML since this will make things more clear. Lets look at some of the shortcomings that MVVM sets out to solve in WPF/XAML.
Data shape vs UI shape
The 'VM' in MVVM creates a set of objects defined in C# that map onto a set of presentation objects defined in XAML. These C# objects are typically connected to XAML via DataContext properties on presentation objects.
As a result, the viewmodel object graph needs to map onto your application's presentation object graph. That's not to say that the mapping needs to be one-to-one, but if a list control is contained by a window control, then there must be a way to get from the window's DataContext object to an object that describes that list's data.
The viewmodel object graph decouples the model object graph from the ui object graph successfully, but at the expense of an additional viewmodel layer that must be built and maintained.
If I want to move some data from screen A to screen B, I need to mess around with viewmodels. In the mind of a business guy, this is a UI change. It should take place purely in the world of XAML. Sadly, it rarely can. Worse, depending on how the viewmodels are structured and how actively the data changes, quite a bit of data re-routing could be required to accomplish this change.
Working around unexpressive data binding
WPF/XAML bindings are insufficiently expressive. You basically get to provide an way to get to an object, a property path to traverse, and binding converters to adapt the data property's value to what the presentation object requires.
If you need to bind a property in C# to anything more complex than that, you're basically out of luck. I've never seen a WPF app without a binding converter that turned true/false into Visible/Collapsed. Many WPF apps also tend to have something called NegatingVisibilityConverter or similar that flips the polarity. This should be setting off alarm bells.
MVVM gives you guidelines for structuring your C# code that can be used to smooth over this limitation. You can expose a property on your viewmodel called SomeButtonVisibility and just bind it to that button's visibility. Your XAML is nice and pretty now...but you've made yourself into a clerk--now you have to expose + update bindings in two places (the UI and the code in C#) when your UI evolves. If you need the same button to be on another screen, you've got to expose a similar property on a viewmodel that that screen can access. Worse, I can't just look at the XAML and see when the button will be visible anymore. As soon as bindings become slightly nontrivial, I have to do detective work in the C# code.
Access to data is aggressively scoped
Since data generally enters the UI via DataContext properties, it's hard to represent global or session data consistently throughout your app.
The idea of the "currently logged in user" is a great example--this is often a truly a global thing within an instance of your app. In WPF/XAML it's very difficult to ensure global access to the current user in a consistent manner.
What I'd like to do is use the word "CurrentUser" in data bindings freely to refer to the currently logged in user. Instead, I have to make sure that every DataContext gives me a way to get to the current user object. MVVM can accomodate this, but the viewmodels are going to be a mess since all of them have to provide access to this global data.
An example where MVVM falls over
Say we have a list of users. Next to each user, we want to display a "delete user" button, but only if the currently logged in user is an admin. Also, users are not allowed to delete themselves.
Your model objects shouldn't know about the currently logged in user--they will just represent user records in your database, but somehow the currently logged in user needs to be exposed to data bindings within your list rows. MVVM dictates that we should create a viewmodel object for each list row that composes the currently logged in user with the user represented by that list row, then expose a property called "DeleteButtonVisibility" or "CanDelete" on that viewmodel object (depending on your feelings about binding converters).
This object is going to look an awful lot like a User object in most other ways--it may need to reflect all of the user model object's properties and forward updates to that data as it changes. This feels really icky--again, MVVM makes you into a clerk by forcing you to maintain this user-workalike object.
Consider--you probably also have to represent your user's properties in a database, the model, and the view. If you have an API between you and your database, then it's worse--they're represented in the database, the API server, the API client, the model, and the view. I'd be really hesitant to adopt a design pattern that added another layer that needs to be touched each time a property is added or changed.
Even worse, this layer scales with the complexity of your UI, not with the complexity of your data model. Often the same data is represented in many places and in your UI--this doesn't only add a layer, it adds layer with a lot of extra surface area!
How things could have been
In the case described above, I'd like to say:
<Button Visibility="{CurrentUser.IsAdmin && CurrentUser.Id != Id}" ... />
CurrentUser would be exposed globally to all XAML in my app. Id would refer to a property on the DataContext for my list row. Visibility would convert from boolean automatically. Any updates to Id, CurrentUser.IsAdmin, CurrentUser, or CurrentUser.Id would trigger an update to this button's visibility. Easy-peasy.
Instead, WPF/XAML forces its users to create a complete mess. As far as I can tell, some creative bloggers slapped a name on that mess and that name was MVVM. Don't be fooled--it is not in the same class as the GoF design patterns. This is an ugly hack to work around an ugly data binding system.
(This approach is sometimes referred to as "Functional Reactive Programming" in case you're looking for further reading).
In Conclusion
If you must work in WPF/XAML, I still don't recommend MVVM.
You want your code to be structured like the "how things could have been" example above would have it--model exposed directly to view, with complex data binding expressions + flexible value coercions. It's way better--more readable, more writable, and more maintainable.
MVVM tells you to structure your code in a more verbose, less maintainable way.
Instead of MVVM, build some stuff to help you approximate the good experience: Develop a convention for exposing global state to your UI consistently. Build yourself some tooling out of binding converters, MultiBinding, etc that allows you to express more complex binding expressions. Build yourself a library of binding converters to help make common coercion cases less painful.
Even better--replace XAML with something more expressive. XAML is a very simple XML format for instantiating C# objects--it wouldn't be hard to come up with a more expressive variant.
My other recommendation: don't use toolkits that force these kinds of compromises. They will hurt the quality of your end product by pushing you towards crap like MVVM instead of focusing on your problem domain.